2009-10-05 64 views
1

我得到一個指向基類的指針(實際上是指向某個派生類的指針)。然後我想調用該派生類的函數,但我不知道它是哪一個。鑄造到一個類並從兄弟類調用函數?

class Base 
{ 

}; 

class DerivedOne : public Base 
{ 
    public: 
     void functionA() 
     { int x = 0; } 
}; 

class DerivedTwo : public Base 
{ 
    public: 
     void functionA() 
     { int x = 0; } 
}; 

int main() 
{ 
    Base* derivedTwoPtr = new DerivedTwo(); 

    reinterpret_cast<DerivedOne*>(derivedTwoPtr)->functionA(); 

    return 0; 
} 

這是按我想要的方式工作,但我不得不說它看起來相當狡猾。它是否定義了行爲?如果沒有,是否有合法的方式來動態解決這個問題?

+1

你已經得到了如何做你想要的答案;回答你的問題的其他部分,不,這完全是未定義的行爲。 – 2009-10-05 07:03:56

回答

6

嘿,不要這樣做。這就是虛擬方法的作用。

class Base 
{ 
public: 
    virtual void functionA()=0; 

}; 

class DerivedOne : public Base 
{ 
    public: 
     virtual void functionA() 
     {  int x = 0;  } 
}; 

class DerivedTwo : public Base 
{ 
    public: 
     virtual void functionA() 
     {  int x = 0;  } 
}; 

int main() 
{ 
    Base* derivedTwoPtr = new DerivedTwo(); 

    derivedTwoPtr->functionA(); 

    return 0; 
} 
2

只需使用虛擬功能。這就是他們的目標。您的基類應該看起來像

class Base 
{ 
    virtual void functionA() = 0; 
}; 

其中= 0位是可選的。如果您想在Base中提供默認實現,請忽略它。如果存在,則虛擬函數被稱爲純虛函數,並強制執行該函數的每個子類Base

現在,如果您通過Base指針呼叫functionA,您將得到適合指針指向的任何子類的方法。

1

基本上你在這裏回答你自己的問題:

演員荷蘭國際集團一類,並呼籲從同級類 功能?

這是我想要的,但我不得不 說它看起來相當狡猾。是否定義了 行爲?如果沒有,是否有 合法的方式動態盟友解決這個問題?

簡而言之:

if (DerivedOne* one=dynamic_cast<DerivedOne*>(BasePtr)) 
    one->functionA(); 
else if (DerivedTwo* two=dynamic_cast<DerivedTwo*>(BasePtr)) 
    two->functionA(); 

但是,是的,就像VAVA說,不這樣做。

+0

同樣的交易,dynamic_cast不能在基類中至少存在一個虛擬方法的情況下工作。 – vava 2009-10-05 10:43:21

1

是否有合法的方式來動態地 解決這個問題?

dynamic_cast可用於轉換爲特定派生類並調用派生類方法。但在你的情況下,最好的辦法是在Base類中提供一個虛擬方法,併爲派生類中的虛擬方法提供不同的實現。

+0

除非基類中有虛方法,否則dynamic_cast將無法正常工作。 – vava 2009-10-05 10:42:29