虛擬繼承與預設建構子呼叫
在涉及虛擬繼承的繼承層次結構中,虛擬基底類別的預設建構子可能會被意外呼叫。考慮以下程式碼:
class grandmother { public: grandmother() { // Default constructor std::cout << "grandmother (default)" << std::endl; } grandmother(int attr) { // Parameterized constructor std::cout << "grandmother: " << attr << std::endl; } }; class mother: virtual public grandmother { public: mother(int attr) : grandmother(attr) { std::cout << "mother: " << attr << std::endl; } }; class daughter: virtual public mother { public: daughter(int attr) : mother(attr) { std::cout << "daughter: " << attr << std::endl; } }; int main() { daughter x(0); }
當建立子類別的實例時,輸出為:
grandmother (default) mother: 0 daughter: 0
儘管祖母類別中存在參數化建構函數,但呼叫預設建構子。為什麼會發生這種情況?
虛擬基底類別建構子的呼叫
在虛擬繼承中,虛擬基底類別的建構子直接被最遠派生類別的建構子呼叫。在這種情況下,子構造函數直接呼叫祖母構造函數。
由於母類沒有在其初始化列表中明確調用祖母構造函數,因此使用預設構造函數。要正確呼叫所需的構造函數,應將子構造函數修改為:
daughter(int attr) : grandmother(attr), mother(attr) { ... }
透過明確呼叫初始化列表中的grandma(attr) 構造函數,使用正確的構造函數,輸出變為:
grandmother: 0 mother: 0 daughter: 0
以上是為什麼在虛擬繼承層次結構中呼叫虛擬基底類別的預設建構子?的詳細內容。更多資訊請關注PHP中文網其他相關文章!