C++的类 (新增 static成员数据初始化,纯虚函数,抽象类)

本文深入探讨C++中的类,包括如何使用类定义、static成员数据和函数的初始化、const成员函数的使用,以及静态对象的生命周期。此外,还详细介绍了纯虚函数和抽象类的概念,强调了它们在多态性和接口设计中的作用。通过实例代码,阐述了动态绑定的概念和应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

感觉这个部分比较重要而且内容比较多,单独写一篇文章

1 对类的初印象[incomplete]

和C程序不一样,在C++中你首先要关心的并不是通过怎样的代码来实现一个类,而是一个类所能进行的所有操作、以及这些操作的效果。我们可以先用伪代码来写出类的定义,再在main函数中使用这个类。

example.h

class Sales_item:

商品

operation <<:

    输入名称、单价、购买数量

operation <<:

    输出名称、单价、购买数量、总价格

operation +:

    名称相同时,单价修改为平均价格,购买数量修改为总数量

    名称不同时,提示错误

operation =:

    修改名称、单价、购买数量 

 

example.c

#include <iostream>

#include "example.cxx"

int main()

{

    Sales_item book;

    std::cin >> book;

    std::cout<<book<<std::endl;

    Sales_item book2;

    std::cin>>book2;

    std::cout<<book+book2<<std::endl;

    book=book2;

    std::cout<<book<<std::endl;

}

  

2 static数据成员、static成员函数

如果我们要求一个类的所有对象共享一个数据,我们可以把这个数据定义成static类型的成员数据;同样,如果希望所有的对象共享一个成员函数,我们可以定义static 成员函数

调用static成员函数的三种方法:

假设animal类有一个成员函数 animal::population()

animal guest;

animal* guestAddress=&guest;

guest.population();

guestAddress->population();

animal::population();

 

3 const成员函数

定义方式:在结尾加关键字“const”

const_function_type myConstFunction(...) const

含义:这个函数不会改变对象的成员数据

标记为mutable的成员数据除外:const对象的mutable成员数据也可以被修改,而且const成员函数可以修改mutable成员数据。

4 static objects of some class/singleton

有时候我们在程序中需要用到一些相关的常量,这些常量都和某一个具体对象相关,例如太阳这个对象——我们希望能在整个程序中随时使用太阳的质量、半径、表面重力加速度、热功率等等,我们还希望能随时打印太阳的所有参数。我们可以定义一些全局常量,但是这样并不符合面向对象编程的思想,而且也不能体现这些参数之间的关系。而最好的解决办法就是创建一个只有一个对象(singleton)的类。

先看例子:

http://www.codeproject.com/Articles/1921/Singleton-Pattern-its-implementation-with-C

可以看到这个类有一个static成员数据single,而且这个成员数据恰好是Single类类型的。

由于static类型的数据在main函数开始前就已经初始化好了,

5 静态成员数据赋初值

赋初值需要1 在内存中分配空间 2 将初始化数据写入所分配的内存空间

假设有一个类

MyClass.h

#include "anotherClass.hh"

class MyClass

{

    public:

         static int staticIntObject;  

        static anotherClass* staticAnotherClassObject;

        int IntObject;

        anotherClass* AnotherClassObject;

        static bool initialize();

   private:

        MyClass(){}

        ~MyClass(){}

};

anotherClass.hh

class anotherClass

{

     public:

        anotherClass(){}

        ~anotherClass(){}

};

在MyClass.cc文件中,由于构造函数是私有的:

MyClass MyClassObject;语句是非法的。因为需要调用构造函数。

MyClass* MyClassObjectPointer=new MyClass;是非法的。因为需要调用构造函数。

MyClass* MyClassObjectPointer;是合法语句,不会调用构造函数。

对于static类型的数据成员:

编译器会在整个程序中搜索静态成员数据的初始化语句,如果没有找到则无法初始化。见这个:

http://blog.youkuaiyun.com/lwl_ls/article/details/3919028 

在类类定义之外给静态成员数据赋初值

        这是因为被static声明的类静态数据成员,其实体远在main()函数开始之前就已经在全局数据段中诞生了(见《Inside   The   C++   Object   Model》page247)!其生命期和类对象是异步的,(而且静态语意说明即使没有类实体的存在,其静态数据成员的实体也是存的)这个时候对象的生命期还没有开始,如果你要到类中去初始化类静态数据成员,让静态数据成员的初始化依赖于类的实体,,那怎么满足前述静态语意呢?难道类永远不被实例化,我们就永远不能访问到被初始化的静态数据成员吗?

MyClass.cc

#include "MyClass.hh"

#include "anotherClass.hh"

int MyClass::staticIntObject=1;

anotherClass MyClass::staticAnotherClassObject;   //anotherClass类型静态数据成员赋初值,会调用构造函数

bool MyClass::initialize() //无需重复static保留字

{

    if(staticAnotherClassObject=new anotherClass()) //此时会调用anotherClass的构造函数

         return true;

    else

         return false;

}

main.cc

#include <iostream>

#include "MyClass.hh"

int main()

{

    MyClass::initialize();

    std::coud<<MyClass::staticIntObject<<std::endl;

    return 0;

}

6 纯虚函数

在类声明体中某一成员函数形参表后加“=0”表示声明此成员函数为纯虚函数。

只有虚函数才能是纯虚函数。

7 抽象类

如果一个类中至少有一个成员函数为纯虚函数,则这个类为抽象类。

不能定义抽象类类型的对象、或给指向抽象类类型的指针分配空间,但是可以定义一个(未初始化或空的)指向抽象类类型的指针。

*  virtual 虚函数 [incomplete]

先要解释动态绑定。假设有两个类Animal类和Human类,其中Human类是基类Animal的一个派生类。我们可以定义一个对象guest为Animal类:

Animal guest;

然后又定义两个对象

Animal dog;和Human Jack;

假设Animal类下有一个成员函数为sayhello(),其内容是Animal::sayhello(){cout<<"Hi!"<<endl;},则Human类会继承这个成员函数。

现在我们在Human类中重定义这个函数为Human::sayhello(){cout<<"Let's shake hands."<<endl;};

现在我们来做一个实验

guest=dog;

guest.sayhello();

guest=Jack;

guset.sayhello();

结果怎么样?

我们现在在原来Animal类声明中在sayhello的声明前加上关键字 virtual,再来一遍,结果又怎么样?

 

#ifndef def
#define def 1

#include <iostream>
using namespace std;

class Animal {
Public:
void sayhello(){cout<<"Hi!"<<endl;}
};
class Human:public Animal
{
Public:
void sayhello(){cout<<"Let's shake hands."<<endl;}
};
#endif

 

#include <iostream>
#include "def.hh"
int main()
{
Animal guest;
Animal dog;
Human Jack;
guest=dog;
guest.sayhello();
guest=Jack;
guest.sayhello();
return 0;
}

编译还没通过,慢慢改

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值