Hin*_*sum 2 c++ initialization class list derived
我有以下计划:
#include<iostream>
using namespace std;
struct Base01{
int m;
Base01():m(2){}
void p(){cout<<m<<endl;}
};
struct Derived01:public Base01{
Derived01():m(3){}
};
struct Derived02:virtual public Base01{
Derived01():m(4){}
};
struct my: Derived01,Derived02{
my():m(5){}
};
int main(){
return 0;
}
Run Code Online (Sandbox Code Playgroud)
gcc/clang都报告编译错误.
我只想知道这里的语言设计考虑是什么,为什么派生类只能在初始化列表中调用基类ctor,但不能直接使用基类成员?
您在构造函数初始化列表中执行的操作是初始化.它只能在对象的生命周期中完成一次.一般情况下,这就是启动对象生命周期的原因.
基类的构造函数(在派生类的构造函数正确变为活动状态之前完成工作)已经初始化了基类的所有直接子对象.它已经开始了他们的一生.如果您尝试从派生类的构造函数中伸入并初始化基类的直接子对象,那么这显然是同一对象的第二次初始化.这在C++中是完全不可接受的.语言设计通常不允许您第二次初始化某些内容.
在您的情况下,所讨论的子对象具有基本类型int,因此很难看到这种"重新初始化"的危害.但是考虑一些不那么微不足道的东西,比如一个std::string物体.你如何建议派生类应该"撤消并重做"已经由基类执行的初始化?虽然正式地可以正确地执行它,但构造函数初始化程序列表并非用于此目的.
在一般情况下,做这样的事情,要求语言功能,允许用户告诉基类的构造沿东西线"请留下你的这个子对象初始化,我才能够达到,并从派生类后初始化" .但是,C++不为用户提供此类功能.虚拟基类初始化中存在一个模糊的类似特征,但它有一个非常特定(和不同)的目的.