目录
定义
构造函数链
构造函数链是指在类继承中,子类的构造函数可以显式调用其直接父类的构造函数,以确保基类和派生类的成员都被正确初始化。
委托构造函数
C++11引入了委托构造函数的概念,它允许一个构造函数调用类的另一个构造函数,以减少代码的重复和提高可维护性。
前言
代码错误
在讲解委托构造函数和构造函数链之前,我们来看这样一段错误代码
代码纠正
创建一个继承A类的B类,程序发生错误,观察报错信息,提示no matching function for call ‘A::A()’,即没有A()的空参构造函数。如果加上A的空参构造函数,结果如下:
解析
构造函数链
前文提及,子类构造函数可以显式调用父类的构造函数。实际上如果没有显式调用父类构造函数,会自动调用父类的默认构造函数。
这解释了”前言“中的程序错误问题,我在父类A中写且只写了有参构造函数,而并未在B类显示调用A类构造函数。导致子类B默认调用A的无参构造函数,可是我已经写了A的有参构造函数,导致A的无参构造函数被删除。
因此,B类无法找到A类无参构造函数,从而报错。
我在”前言“中的解决办法是写A的无参构造函数,但例外一个办法是只需要使B显式调用A的有参构造函数即可,其用法和结果如图:
可见,构造函数链的用法与成员初始化列表的用法相似,若二者结合,依旧有效,不论顺序先后且用逗号分隔。结果如下:
委托构造函数
在了解构造函数链的机制之后,委托构造函数与之类似。
委托构造函数是构造函数调用”同类“的其他构造函数,在运行完所指明的”同类“其他构造函数之后再运行自己的构造函数。
但与之不同的是委托构造函数并非必要步骤,可自由选择使用,不同于构造函数链的:若不显式调用则调用父类默认构造函数。
且二者作用范围虽然都是构造函数,但是前者为同类的构造函数,后者为父类的构造函数
实验代码如下:
我们看到,main函数使用B的有参构造函数创建对象,
在B的有参构造函数中,委托B的无参构造函数进行构造,而B的无参构造又会在构造函数链中调用父类A的默认构造函数,所以优先打印A的无参构造函数,再打印B的无参构造函数,最后再打印B的有参构造函数
运行代码
#include<iostream>
using namespace std;
class A{
public:
A(){
cout<<"A无参构造函数"<<endl;
}
A(int age){
cout<<"A有参构造函数"<<endl;
this->age=age;
}
int age;
};
class B:public A{
public:
B(){
cout<<"B无参构造函数"<<endl;
}
B(string name):B(){
cout<<"B有参构造函数"<<endl;
this->name=name;
}
string name;
};
int main (){
B b("tom");
return 0;
}
总结
构造函数链和委托构造函数的目的都是为了优化类中的构造函数所采取的办法,
构造函数链调用父类构造函数以确保初始化的正确性,
委托构造函数委托同类构造函数以减少重复代码的使用率,优化代码结构。