C++继承中派生类的构造函数那些事儿~~~
我们知道,构造方法是用来初始化类对象的。如果在类中没有显式地声明构造函数,那么编译器会自动创建一个默认的构造函数,一般是以下四种情况:
- A类中包含有B类的对象,A类没有显式定义构造函数,B类带有无参的或者全缺省的构造函数
- B类继承自A类,A类没有显式定义任何构造函数,B类带有无参或者全缺省的构造函数
- 在虚拟继承中,编译器一定会给子类生成构造函数(前四个字节存放虚表地址)
- 类中如果包含有虚函数,编译器一定会给该类生成构造函数
构造函数和析构函数不能被子类继承。因此,在创建子类对象时,为了初始化从父类中继承来的成员变量,编译器需要调用其父类的构造函数。如果子类的构造函数没有显示地调用父类的构造函数,则默认调用父类的无参构造函数。
1. 如果基类没有显式添加任何构造函数,则子类也可以不用添加(或者子类根据是否需要选择性添加)
class Base
{
public:
void SetBase(int b)
{
_b = b;
}
int _b;
};
class Derived : public Base
{
public:
// 根据是否需要自行添加
Derived()
{
cout << "Derived():" << this << endl;
}
void SetDerived(int b, int d)
{
_b = b;
_d = d;
}
public:
int _d;
};
2. 如果基类具有无参或者全缺省的构造函数,则子类也可以不用添加(或者子类根据是否需要选择性添加)
class Base
{
public:
Base(int b = 10)
: _b(b)
{
}
void SetBase(int b)
{
_b = b;
}
int _b;
};
class Derived : public Base
{
public:
/*
如果用户没有显式给子类定义构造函数时,则编译器会给子类生成一份默认的构造函数
Derived()
: Base()
, _d(随机值)
{}
*/
Derived(int b, int d)
: Base(b)
, _d(d)
{
_b = b;
_d = d;
}
void SetDerived(int b, int d)
{
_b = b;
_d = d;
}
public:
int _d;
};
3. 如果基类具有带参构造函数(注意不是全缺省的),则子类必须要显式定义自己的构造函数而且必须在其构造函数初始化列表的位置对基类继承下来的成员显式初始化
class Base
{
public:
Base(int b)
: _b(b)
{
}
void SetBase(int b)
{
_b = b;
}
int _b;
};
// 注意:不能再子类构造函数初始化类表的位置显式初始化基类继承下来的成员变量
class Derived : public Base
{
public:
/*
如果用户没有显式定义构造函数时,则编译会给子类生成一个无参的构造函数,则此时基类构造函数一定会传参失败
Derived()
: Base()
, _b(随机值)
{}
*/
Derived(int b, int d)
: Base(b)
, _d(d)
{
}
void SetDerived(int b, int d)
{
_b = b;
_d = d;
}
public:
int _d;
};