摘要#
可以說普通繼承是先構造基類再構造派生類,而虛繼承將基類嵌入到派生類中只構造一次,以確保虛基類只被構造一次。
當基類的構造函數包含輸出語句 "constructor" 時,在虛繼承和普通繼承的情況下會有不同的輸出結果。
考慮以下示例代碼:
#include <iostream>
class Base {
public:
Base() {
std::cout << "constructor" << std::endl;
}
};
class Derived : public virtual Base {
public:
Derived() : Base() {
}
};
int main() {
Derived d;
return 0;
}
在上述代碼中,Derived
類通過虛繼承方式繼承了Base
類,並在構造函數中調用了基類的構造函數。當我們運行此代碼時,會發現只輸出一次 "constructor"。這是因為虛繼承保證了虛基類(在這裡是Base
類)只被構造一次,即使在多層繼承中也是如此。所以在派生類Derived
的構造函數中只會調用一次基類Base
的構造函數。
現在考慮使用普通繼承的情況:
#include <iostream>
class Base {
public:
Base() {
std::cout << "constructor" << std::endl;
}
};
class Derived : public Base {
public:
Derived() : Base() {
}
};
int main() {
Derived d;
return 0;
}
在這個例子中,Derived
類通過普通繼承方式繼承了Base
類,並在構造函數中調用了基類的構造函數。運行這段代碼時,會輸出兩次 "constructor",一次來自於基類的構造函數調用,另一次來自派生類的構造函數調用。
因此,虛繼承確保虛基類只被構造一次,而普通繼承會在每個繼承層次中都調用基類的構造函數。這是虛繼承與普通繼承在構造函數調用方面的一個重要區別。
在虛繼承的情況下,一次輸出 "constructor" 來自於最終派生類的構造函數調用基類的構造函數。
考慮以下示例代碼:
#include <iostream>
class Base {
public:
Base() {
std::cout << "constructor" << std::endl;
}
};
class Intermediate : public virtual Base {
public:
Intermediate() : Base() {
}
};
class Derived : public Intermediate {
public:
Derived() : Intermediate() {
}
};
int main() {
Derived d;
return 0;
}
在這個例子中,存在一個中間類 Intermediate
,它通過虛繼承方式繼承了 Base
類。派生類 Derived
通過繼承 Intermediate
類來間接虛繼承 Base
類。
當我們運行這段代碼時,只會輸出一次 "constructor"。這一次輸出來自於最終派生類 Derived
的構造函數調用 Intermediate
類的構造函數,而 Intermediate
類的構造函數又調用了基類 Base
的構造函數。
因此,在虛繼承中,一次輸出 "constructor" 來自於最終派生類的構造函數調用虛基類的構造函數。這確保了虛基類只被構造一次。
在普通繼承中,構造派生類對象時,首先會先構造基類部分,然後在此基礎上構造派生類部分。這意味著基類的構造函數會在派生類的構造函數之前被調用。因此,在普通繼承中,先構造基類,再構造派生類。
而在虛繼承中,基類的構造函數只會被調用一次,無論繼承關係的層次有多深。虛繼承引入了額外的指針或機制,將虛基類嵌入到派生類中,以確保虛基類只被構造一次。在派生類的構造函數調用鏈中,最終派生類負責調用虛基類的構造函數,而不是每個派生類都去調用基類的構造函數。
所以,可以說普通繼承是先構造基類再構造派生類,而虛繼承將基類嵌入到派生類中只構造一次,以確保虛基類只被構造一次。
這種區別是為了解決多重繼承中的問題,如菱形繼承問題,虛繼承的引入使得在多重繼承的情況下能夠更靈活地管理和初始化基類部分的成員。
所以普通構造相當於先構造一個基類再在此基礎上構造派生類?虛繼承相當於將基類嵌入派生類只構造一次?
在普通繼承中,構造派生類對象時,首先會先構造基類部分,然後在此基礎上構造派生類部分。這意味著基類的構造函數會在派生類的構造函數之前被調用。因此,在普通繼承中,先構造基類,再構造派生類。
而在虛繼承中,基類的構造函數只會被調用一次,無論繼承關係的層次有多深。虛繼承引入了額外的指針或機制,將虛基類嵌入到派生類中,以確保虛基類只被構造一次。在派生類的構造函數調用鏈中,最終派生類負責調用虛基類的構造函數,而不是每個派生類都去調用基類的構造函數。
總結#
所以,可以說普通繼承是先構造基類再構造派生類,而虛繼承將基類嵌入到派生類中只構造一次,以確保虛基類只被構造一次。
這種區別是為了解決多重繼承中的問題,如菱形繼承問題,虛繼承的引入使得在多重繼承的情況下能夠更靈活地管理和初始化基類部分的成員。