c++ - 为什么C++不允许派生类在初始化列表中使用基类成员?

标签 c++ list class initialization 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; 
} 

gcc/clang 都报告编译错误。

我只是想知道这里的语言设计考虑是什么,为什么派生类只能调用初始化列表中的基类ctor,而不能直接使用基类成员?

最佳答案

您在构造函数初始化列表中所做的是初始化。这是在对象的生命周期内必须做一次的事情。在一般情况下,这就是对象生命周期 的开始。

基类的构造函数(在派生类的构造函数被激活之前完成工作)已经初始化了基类的所有直接子对象。它已经开始了他们的生命。如果您试图从派生类的构造函数中获取并初始化基类的直接子对象,那显然是同一对象的第二次初始化。这在 C++ 中是完全不能接受的。语言设计一般不允许你对某些东西进行第二次初始化。

在您的情况下,所讨论的子对象具有基本类型 int,因此很难看出这种“重新初始化”的危害。但是考虑一些不那么琐碎的东西,比如 std::string 对象。你如何建议派生类应该“撤消和重做”基类已经执行的初始化?虽然形式上可以正确地做到这一点,但构造函数初始值设定项列表并非用于此目的。

在一般情况下,做这样的事情需要一种语言特性,允许用户告诉基类的构造函数类似“请不要初始化你的这个子对象,我稍后会从派生类”。然而,C++ 并没有为用户提供这样的能力。虚拟基类初始化中存在一个模糊相似的功能,但它服务于非常具体(且不同)的目的。

关于c++ - 为什么C++不允许派生类在初始化列表中使用基类成员?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44992894/

相关文章:

c++ - 何时使用 STL 位集而不是单独的变量?

jquery - 在jquery中创建嵌套列表

c++ - 如何通过函数(不在任何类中)在类中使用私有(private)变量?

c# - 根据属性比较两个 List<Control> 之前/之后

java - java中的错误排序字母列表

c++ - 访问 C++ 父类的私有(private)成员

c++ - 打印对象数组的每个元素时出现问题

c++ - 函数返回的字符串文字的生命周期

C++ 字符串中的回车和换行

c++ - 多个成员函数前向声明