子类初始化列表不能初始化父类元素 -- class 'Derived' does not have any field named 'x'
緣由
偶爾編寫如下代碼,編譯出錯,
class Base{ public:int x; };class Derived : public Base { public:Derived() : x(10) {cout << "Derived " << x << endl;};int y; };int main() {Base *p = new Derived(); }錯誤:
D:\CLionProjects\Demo\main.cpp: In constructor ‘Derived::Derived()’:
D:\CLionProjects\Demo\main.cpp:45:17: error: class ‘Derived’ does not have any field named ‘x’
Derived() : x(10) {
錯誤是子類的構造方法的初始化列表中無法初始化父類成員變量。那么是為什么呢?本文從如下幾個方面進行思考討論?
初始化列表為何物,為何要在初始化列表中初始化變量?
當我們定義變量時習慣于對其進行初始化,而非先定義,再賦值:
string foo = "Hello World!"; // 定義并初始化 string bar; // 默認初始化為空string對象 bar = "Hello World!"; // 為bar賦一個新值。就對象的數據成員而言,初始化和賦值也有類似的區別,如果沒有在構造函數的初始化列表中顯示地初始化成員,則該成員將在構造函數體之前執行默認初始化,例如:
class Demo { public:Demo(string name) { // 此處隱式的對name進行了初始化this->name = name; // 此處是賦值,并非初始化}; private:string name; };有很多地方強調要使用初始化列表進行變量的賦值,為何呢?個人匯總如下:
初始化列表,構造函數的執行順序如何?
正如上面所述,初始化列表是在構造函數體之前執行:
struct P {P(){cout << "P construct" << endl;}; }; class Base { public:Base():p(P()){cout << "Base construct" << endl;};P p; };int main() {Base p; }運行結果:
P construct
Base construct
執行順序:父類初始化列表-> 父類構造函數->子類初始化列表->子類構造函數。
c++ 子類 父類的對象模型是如何的?
class Base { public:int x; };class Derived :: Base { public:int y; };int main() {Base *base = new Derived(); }總結
猜測可能是如下原因:
個人傾向于編譯行為,不能再子類的初始化列表顯示的父類的成員變量進行初始化;如果需要,在初始化列表中包含父類的相應構造方法(含有初始化列表)。
總結
以上是生活随笔為你收集整理的子类初始化列表不能初始化父类元素 -- class 'Derived' does not have any field named 'x'的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php开发discuz插件,discuz
- 下一篇: “百度百科六度分隔理论”(简单版)