2016-02-12 60 views
3

我有2個類,AB,我需要從A的構造函數調用B中的覆蓋函數。以下是我已經:從基類派生的C++調用覆蓋函數

class A { 
    A(char* str) { 
     this->foo(); 
    } 

    virtual void foo(){} 
} 

class B : public A { 
    B(char* str) : A(str) {} 

    void foo(){ 
     //stuff here isn't being called 
    } 
} 

如何我會得到的代碼是在B::foo()A::A()叫什麼名字?

+2

不要在構造函數中使用虛函數。當構造B時,首先構造A。此時B的額外方法/變量尚未建立。所以事情可能會非常糟糕。 –

回答

3

我在C++需要在B中的被覆蓋的函數從A的構造

這種設計稱爲是不可能的:一個B對象的order of construction是第一基體A的子對象被構造,那麼B就構成它的頂部。

結果是,在A構造函數中,您仍在構造一個A對象:此時調用的任何虛函數都將是A的虛函數。只有A構造完成且B構造啓動時,纔會B的虛擬功能變得有效。

爲了實現你想要的,你必須使用兩步模式:1)構造對象,2)初始化它。

+0

好。我認爲這裏需要一個很好的進一步說明,這也解釋了爲什麼這是C++的設計;也就是說,假設虛擬函數的內容和它們的期望是有危險的(例如一些成員已經被初始化)。 –

+0

@YamMarcovic Bjarne Stroustrup在「Design&Evolution of C++」中解釋了基礎優先邏輯的理性,p283:如果在構建過程中調用覆蓋函數,它將不知道哪些成員已經構建或者沒有構建,以及每一個被覆蓋的函數都必須爲構造函數保留最大的謹慎和偏執狂。 – Christophe

+1

這正是我的意思 - 對不起,如果不明確。我認爲這可能是一個很好的補充提到它的答案。 –

3

我想你指的是調用虛函數在初始化過程成語(又名動態綁定初始化期間),因此,請在這裏看看,這裏的一切都解釋說:

  1. https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Calling_Virtuals_During_Initialization
  2. https://isocpp.org/wiki/faq/strange-inheritance#calling-virtuals-from-ctor-idiom

第二個網站有很好的解釋,但它比第一個更長。

+0

可悲的是,這不會對我有用,但它很有趣,謝謝。 – Marc

+0

你能解釋一下爲什麼?也許我可以幫忙。 –

+0

對我來說,這是一個具體的例子,我在我的基類中的具體構造函數類似'init變量 - > make對象 - > run loop',所以我試圖使用的函數是make對象。所以相反,我翻轉我的基類有2個函數'init()'和'start()',並在函數調用之間調用'makeObjects()' – Marc

1

在構造函數中,基類的函數將被調用,而不是被覆蓋的版本。原因是,使用你的例子,當調用A的構造函數時,B的初始化未完成,因此如果以其他方式允許,則調用Bfoo將使用不完整的B實例完成。

相關問題