我有以下具有虛擬GrandParent和非虛擬Parent和的類層次結構Child:
class GrandParent {
protected:
explicit GrandParent(const float &max_dur);
virtual ~GrandParent() {}
private:
const float _max_dur;
};
class Parent : public virtual GrandParent {
public:
explicit Parent(const float &max_dur = 0);
};
class Child : public Parent {
public:
explicit Child(const float &max_dur = 0);
};
它們的建構式嵌套如下:
// GrandParent constructor
GrandParent::GrandParent(const float &max_dur)
: _max_dur{max_dur} {}
// Use GrandParent constructor
Parent::Parent(const float &max_dur)
: GrandParent{max_dur} {}
// Use Parent constructor
Child::Child(const float &max_dur)
: Parent{max_dur} {} // <- error occurs here
當我構建時,我收到以下錯誤訊息:
error: no matching function for call to ‘GrandParent::GrandParent()’
代碼片段在這里。
似乎Child建構式被忽略了,而是跳轉到了GrandParent。修改Child建構式以直接呼叫GrandParent建構式(從而跳過一代),我可以繞過錯誤,但這似乎是錯誤的方法。
在此先感謝您的幫助!
解決方案
通過遵循463035818-is-not-a-number 的答案GrandParent明確呼叫's 的建構式和康煥偉的建議,以便也呼叫Parent's 的建構式:
Child::Child(const float &max_dur)
: GrandParent{max_dur}, Parent{max_dur} {}
uj5u.com熱心網友回復:
從常見問題:
當我從使用虛擬繼承的類繼承時,我需要了解哪些特殊注意事項?
大多數派生類的建構式的初始化串列直接呼叫虛擬基類的建構式。
因為一個虛擬基類子物件在一個實體中只出現一次,所以有一些特殊的規則來確保每個實體只呼叫虛擬基類的建構式和解構式一次。C 規則說虛擬基類在所有非虛擬基類之前構造。作為程式員,您需要知道的是:在您的類的繼承層次結構中任何位置的虛擬基類的建構式都由“派生最多”的類的建構式呼叫。
的構造Child函式GrandParent直接呼叫的建構式,因為GrandParent是虛基。并且因為您沒有顯式呼叫它,所以呼叫了GrandParent默認建構式,但沒有默認建構式。
修改 Child 建構式以直接呼叫 GrandParent 建構式(從而跳過一代),我可以繞過錯誤,但這似乎是錯誤的方法。
這正是正確的方法。Childs 建構式確實呼叫了GrandParents 建構式,當GrandParent它是虛擬基類并且Child是最派生的類時,您對此無能為力。您可以做的是:選擇正確的建構式,而不是讓編譯器嘗試呼叫不存在的默認建構式。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/325645.html
上一篇:通過基類參考訪問派生類成員
