类
- 默认构造函数(只能有一个):
- 不带参数的默认构造函数。如
Test()
- 带有参数且所有参数都有默认值的构造函数。如
Test(int = 1,double = 2)
- 不带参数的默认构造函数。如
如果二者都有的话,会产生二义性,比如Test one
,此时匹配上方任意一个都可以,因此只能二选一。
- 复制构造函数(默认为
Class_name(const Class_name &)
)- 当新建一个对象,并将其初始化为同类现有对象时,复制构造函数将被调用
- 每当程序生成了对象的副本时,编译器都将使用复制构造函数。具体地说,当函数按值传递对象或者返回对象时,都将使用复制构造函数。按值传递意味着创建原始变量的一个副本。
由于按值传递对象将调用复制构造函数,因此应该按引用传递对象。这样可以节省调用构造函数的时间以及存储新对象的空间。
-
赋值运算符
- 将已有对象赋给另一个对象时,重载的赋值运算符将被调用
-
初始化列表
Class::Class(int n,int m) : mem_1(n),mem_2(m)
- 采用这种方式时,初始化工作是在对象创建时完成的,而不是之后
- 这种格式只适用于构造函数
- 必须用这种格式来初始化
非静态const数据成员
、引用数据成员
-
更好的选择:
- C++ 11 允许以下面这种方式进行初始化,与使用初始化列表等价
class my_class { int mem_1 = 10; int mem_2 = 20; // ... }
-
只要类方法不修改调用对象,就应该将其声明
const
-
派生类
- 派生类不能直接访问基类的私有成员,必须通过基类的方法进行访问
- 派生类的构造函数:
- 派生类构造函数应通过成员初始化列表将基类信息传递给基类构造函数
- 派生类构造函数初始化派生类新增的数据成员
- 派生类的构造函数总是要调用一个基类的构造函数
-
继承
- 基类指针或引用可以指向派生类,但是不能反过来
- 使用引用或继承时,如果使用
vitual
,程序将根据引用或指针指向的对象的类型来选择方法。如果没有使用virtual
,程序将根据引用或指针类型来选择方法。 - 在基类方法的声明中使用
virtual
可使该方法在基类以及所有的派生类(包括从派生类派生出来的类)中是虚的。 - 构造函数不能是虚函数,析构函数应该是虚函数,友元不能是虚函数。
- 重新定义继承的方法并不是重载,而是覆盖掉原方法。
- 如果在派生类中重新定义了基类几个重载函数当中的一个版本,则其它版本将被隐藏,派生类对象无法使用它们,因此如果要在派生类中重新定义,就应该重新定义所有的基类版本。
-
虚函数与纯虚函数
- 虚函数:使用引用或继承时,程序将根据引用或指针指向的对象的类型来选择方法。
- 基类的析构函数应该是虚的,不然将只会调用基类的析构函数而不会调用派生类的。
- 构造函数不能是虚函数,没有任何意义,派生类总是会先调用基类的构造函数,然后又调用自己的构造函数。
- 纯虚函数:可以不实现,主要用在基类上来进行派生。
- 虚函数:使用引用或继承时,程序将根据引用或指针指向的对象的类型来选择方法。
-
虚函数的实现机制
- 编译器会给每个对象添加一个隐藏成员,隐藏成员中保存了一个指向函数地址数组的指针,这个数组叫做虚函数表,其中保存了这个类里各个虚函数的地址