今天遇見了一個挺逗的問題,這個問題已經不是第一次絆腳了。放到這里,提醒自己的同時,也相信學習C++的朋友一定都會經歷同樣的問題。
還是老風格,先看代碼:
1 class A 2 { 3 public: 4 A(int a) 5 { 6 } 7 }; 8 class B : public A 9 { 10 11 }; 12 13 int main() 14 { 15 B b(); 16 }
編譯器在自動合成構造函數的時候,會調用子類的默認構造函數。但是,我故意修改了子類A的構造函數,使編譯器不會合成A的無參數的默認構造函數,導致B的默認構造函數無法合成。
我本意是想測試這樣的錯誤。發現上面的代碼居然可以順利編譯通過。
但是,我把第15行代碼 B b(); 改成 B b; 發現,成功的觸發了編譯錯誤。
為什么呢?
在C++中調用構造函數的方式有如下幾種:
A a = A();//調用默認構造函數
A a = A(xx);//調用帶參的構造函數
A a(xx);//調用帶參的構造函數的簡寫形式
A a;//調用默認構造函數的簡寫形式
我們學習東西的時候,不能隨便遷移知識。
上面代碼中第15行B b();其實是聲明了一個函數,該函數沒有參數,返回B類型的變量。整個過程沒有類B變量的定義,所以沒有觸發編譯器去合成B的構造函數,所以沒有報錯。
調用默認構造函數的方法只有兩種,
A a = A();
或者它的簡寫形式:
A a;
而帶參的簡寫形式不能應用在無參的構造式:
A a();
上面這個語句會被識別成無參的函數聲明,函數名是a。