2010-11-03 26 views
1

我知道有些人認爲我不應該從繼承類重新定義非虛函數,但是我現在所做的就是使用這種非常角色遷移的概念,而且它非常適合相當特殊的情況。調用已重新定義的基類非虛函數?

我想是這樣的(哦,這是C++):

class A { 
public: 
void f() { doSomethingA(); } 
}; 
class B : public A { 
public: 
void f() { A::f(); doSomethingB(); } 
}; 

然而,當我這樣做,A::f被稱爲與this == 0,這顯然會導致段錯誤。我做錯了什麼,或者這是不可能的?我目前的選擇是訴諸靜態函數,並明確傳遞對象,但我更喜歡這種方式。

是的,我可以以不同的方式對它們進行調用,但是這樣做會使它們看起來與程序員相似。我不能讓它們因爲各種原因而變得虛擬(最突出的是角色遷移,實際上我需要不同的行爲,這取決於我使用它的方式)。

任何幫助表示讚賞

編輯
謝謝大家的回答,看來我已經在我的構建環境時的錯誤迷迷糊糊的,最小的測試用例細跑;轉向優化也是如此。我想我可以在問這個問題之前嘗試過,但我通常認爲我做錯了什麼。

沒什麼可在這裏看到,沿着移動..很抱歉給您帶來不便... :)

+0

您的'B'不會從'A'繼承...錯字?除此之外,這段代碼實際上應該可以工作。 – 2010-11-03 15:15:47

+0

@Konrad;是的,錯字,對不起。 – falstro 2010-11-03 15:18:09

+0

@Konrad;我仔細檢查了一下,代碼中沒有輸入錯誤,但是我正在盯着gdb中的調用堆棧,它明確指出了'B :: f(this = 0xffbfdb40)'後面跟着'A :: f(this =爲0x0)'。 – falstro 2010-11-03 15:27:05

回答

1

你沒有指定B,從A繼承:

class B : public A { 
+0

是的,那是一個錯字,對不起。 – falstro 2010-11-03 15:24:17

+0

@roe:在這種情況下,調用代碼是什麼樣的? – 2010-11-03 15:32:31

1

假設B不能繼承從A是一個錯字(我看不到這個編譯),它看起來像B指針,你最初調用f爲空。檢查原始的呼叫點,因爲(假設錯字)你寫的內容應該工作。

+0

是的,那是一個錯字,對不起。我仔細檢查過,代碼中沒有輸入錯誤,但是我正在盯着gdb中的調用堆棧,它明確指出'B :: f(this = 0x123123)'後面跟着'A :: f(this =爲0x0)'。 – falstro 2010-11-03 15:25:29

+0

你可以將你的代碼稍微擴展成一個展示該問題的小型完全可運行示例嗎? – 2010-11-03 15:33:42

1

你的代碼似乎不符合文本。在本文中,您將討論繼承,但代碼不會顯示任何(至少按原樣,它甚至不應該編譯)。

如果使用繼承:

class A { 
public: 
    void f() { doSomethingA(); } 
}; 

class B : public A { 
public: 
    void f() { A::f(); doSomethingB(); } 
}; 

然後,當你調用A::f()this一定要是一個空指針 - 它應該是一個有效的指針在BA「子對象」對象(只要你使用單繼承,對於大多數編譯器,它將是你調用B::f()的對象的地址,只是從B * const轉換到A * const)。

0

忽略這樣做的「正確性」,您描述的內容沒有任何問題。我假設你的示例代碼看起來更像以下,雖然實際上有您所描述的繼承:

struct A { 
void f() { cout << "hi" << endl; } 
}; 
struct B : public A { 
void f() { A::f(); } 
}; 
1

嘗試

static_cast<A*>(this)->f() 

應該工作。

編輯:

如果它不,檢查thisB::f()首先的。

相關問題