E09不能在构造/析构函数中调用虚函数
- 在调用派生类的构造函数时,会先调用其基类的构造函数。如果基类的构造函数中有虚函数,这时调用的是基类版本(本应该是派生类)的虚函数。
在调用派生类的析构函数时,派生类的成员呈未定义值,无法再调用派生类的虚函数。
此时可以将该虚函数改成接受一个参数的非虚函数,同时使基类构造函数接受该参数。之后在派生类的构造函数中将形参传给基类构造函数。此时能够调用正确版本的函数。EP51constructor(构造函数):
类没有显式的定义构造函数时,编译器会隐式的定义synthesized default constructor(合成的默认构造函数)CP2361.当某成员的类型没有默认构造函数时,编译器无法为该类合成
2.当类中已经有constructor时,可以通过default关键字生成默认构造函数
类名()=default;
//隐式声明为内联函数,在类外定义时使用default则不是内联函数CP449
- constructor initialize list(构造函数初始化列表)
类名(给定实参):
成员1(实参1),…{}
1.最好按照声明次序进行初始化EP29,CP259
2.效率高于函数体拷贝初始化
3.delegating constructor(委托构造函数)CP261
4.converting constructor(转换构造函数)隐式转换为该类型
例如只接收1个实参的构造函数
string a="hi";
/*combine函数需要1个data对象
编译器用a隐式创建了data对象*/
item.combine(a);
/*编译器只会隐式执行1次类类型的转换 CP264
"hi"需要首先转换成string,再转换成data对象
所以此句错误*/
item.combine("hi");
5.继承构造函数CP557
- 只继承其直接基类的构造函数
- 不能继承默认,拷贝和移动构造函数
- 无法继承默认实参
class B:public A{
public:
using A::A:
//不是使名字在该作用域可见
//该构造函数的访问权限不会由于位置而改变
};
使编译器产生下列等价代码
B(…):A(…){}//派生类的新成员被默认初始化