文章目录
- 1.派生类的构造函数
- 2. 派生类构造函数的定义
- 2.组合关系的派生类的构造函数
1.派生类的构造函数
- 在定义派生类时, 派生类并没有把基类的构造函数和析构函数继承下来。
因此, 对继承的基类成员初始化的工作要由派生类的构造函数承担, 同时基类的析构函数也要被派生类的析构函数来调用。
2. 派生类构造函数的定义
- (1)在执行派生类的构造函数时, 使派生类员同时都被初始化。
- (2)基类名(基类构造函数实参列表)”即是调用基类构造函数, 而派生类新增加的数据成员可以在“派生类初始化列表” (尽量在此) 初始化, 也可以在“派生类初始化函数体” 中初始化。
其定义形式如下:
//构造函数和类的名字是一致的
派生类名(形式参数列表) : 基类名(基类构造函数实参列表),派生类初始化列表
{
派生类初始化函数体
}
- 派生类构造函数的调用顺序是:
①调用基类构造函数;
②执行派生类初始化列表;
③执行派生类初始化函数体; - eg:
class Point
{
int x,y;
public:
Point(int a,int b):x(a),y(b){ }//构造函数
};
class Rect:public Point
{
int h,w;//自己的
public:
//参数个数:自己的数据成员+继承的数据成员
//x(a)这样是错误的,因为x是Point类私有的,Rect与Point是继承关系,属于Point类外部的类,
//不能使用Point类私有的数据成员
//使用Point类自己的构造函数进行初始化,而且Point类的构造函数是公有的
Rect(int a, int b, int c ,int d):Point(a, b),h(a),w(d) { }//派生类构造函数
};
2.组合关系的派生类的构造函数
- 假定派生类A和类B的关系是组合关系, 类A中有类B的子对象。
如果类B有默认构造函数(没有参数的构造函数), 或者参数全是默认参数的构造函数, 或者有无参数的构造函数, 那么类A的构造函数中可以不用显式初始化子对象。
编译器总是会自动调用B的构造函数进行初始化。 - 可以在一个类的构造函数中显式地初始化其子对象, 初始化式只能在构造函数初始化列表中,
形式为:
类名(形式参数列表) : 子对象名(子对象构造函数实参列表),类初始化列表
{
类初始化函数体
}
- 调用顺序为:
①调用基类构造函数;
②调用子对象构造函数, 各个子对象时按其声明的次序先后调用;
③执行派生类初始化列表;
④执行派生类初始化函数体; - 说明:(1)在什么条件下,在派生类中可以不定义构造函数?
如果在基类和子对象所属类的定义中都没有定义带参数的构造函数, 而且也不需要对派生类自己的数据成员初始化, 那么可以不必显式地定义派生类构造函数。
派生类会合成一个默认构造函数(系统自动生成),并在调用派生类构造函数时, 会自动先调用基类的默认构造函数和子对象所属类的默认构造函数。
eg:
class A { }; //A类没有构造函数,系统会自动生成构造函数,这就是合成默认构造函数,且不带参数
class B { }; //合成默认构造函数
class D: public B //D类通过公有继承B类派生的
{
//基类是B类,子对象所属的类是A类,他俩都没有带参数的构造函数
//所以,D类不需要定义构造函数,所以D类会自动生成构造函数
A a;
}; //派生类合成默认构造函数
- 说明:(2)无参数的构造函数是我们自己定义的,默认构造函数是系统自己生成的
如果在基类中没有定义构造函数, 或定义了没有参数的构造函数, 那么, 在定义派生类构造函数时可以不显式地调用基类构造函数。
在调用派生类构造函数时, 系统会自动先调用基类的无参数构造函数或默认构造函数。
eg:
class B
{
public:
B() { }//无参数构造函数
};
class D:public B
{
D() { }//派生类构造函数不必显式调用基类构造函数
};
- 说明:(3)
如果在基类或子对象所属类的定义中定义了带参数的构造函数, 那么就必须显式地定义派生类构造函数, 并在派生类构造函数中显式地调用基类或子对象所属类的构造函数。
eg:
class A
{
public: A(int) { }
}; //有参数构造函数
class B
{
public: B(int) { }
}; //有参数构造函数
class D: public B
{
D(int x) : a(x),B(x) { } //显式调用基类或子对象构造函数
A a;
};
- 说明:(4)显示调用构造函数,系统会调用带参数的构造函数,若不显示调用构造函数,系统会调用无参数的构造函数
►如果在基类中既定义了无参数的构造函数, 又定义了有参的构造函数(构造函数重载) , 则在定义派生类构造函数时, 既可以显式调用基类构造函数, 也可以不调用基类构造函数。
►在调用派生类构造函数时, 根据构造函数的内容决定调用基类的有参数的构造函数还是无参数的构造函数。
►可以根据派生类的需要决定采用哪一种方式。