2010-11-11 155 views
1

是否有可能重寫C++中的基類方法,就像我們可以在C#中使用override關鍵字一樣?覆蓋基類方法

請幫助 謝謝

回答

6

是。

只要使基本方法virtual
C++沒有override關鍵字;任何具有相同簽名(包括參數類型和const-度)的方法都將作爲基本方法virtual將覆蓋它。

+2

你不需要做出基類虛擬。虛擬基類功能允許您正確使用多態。通常情況下,您可以重寫基類函數,但假設您有一組「形狀」對象指針,則可以將該數組的元素實例化爲派生對象,如「方形」或「三角形」像draw()它通常會調用基類的繪製,除非它是虛擬的,那麼它將查看數組實際指向的是什麼類型,並調用派生類的函數 – thecoshman 2010-11-11 17:27:19

+1

@thecoshman:他要求等價於C#的'override'關鍵字(多態),而不是C#的'new'關鍵字(隱藏)。爲此,你需要'虛擬'。 (即使他不明白這個區別) – SLaks 2010-11-11 17:49:34

+0

好吧,如果你仔細看看C#中的關鍵字'override',它在C++中是不需要的,它隱含地暗示了這兩個函數具有相同的簽名。 – thecoshman 2010-11-11 17:57:59

0

是的,你可以重寫基類方法;如果在基類中使用關鍵字virtual,則該方法的綁定將是動態的(即完全多態);如果您在基類中未使用關鍵字virtual,則該方法的綁定將是靜態的。

+0

它不會被_fully_動態;重載(參數類型)將在編譯時被選中。 – SLaks 2010-11-11 17:22:06

+0

Slaks:真正的dat。 – 2010-11-11 17:36:32

3

只有在C++ 0x中,即將出現的C++語言的標準。在C++ 03中,這是您隱式重寫的當前C++,也就是說,您不要將重寫方法顯式標記爲重寫方法。但要小心,如果你不小心寫了另一個簽名,但名稱相同,基類函數將被隱藏並且不被覆蓋!

struct X 
{ 
    virtual void f() {...}; 
}; 

struct Y:X 
{ 
    void f() {...} //overrides X::f 
}; 

struct Z:X 
{ 
    void f() const {... } //hides X::f!!! 
}; 

可以在功能聲明不同的唯一事情是,如果在基類中的函數返回T1*(或T1&)和衍生T2*類(或T2&)和T2從T1衍生那麼它的行,它仍然是過度的,而不是隱藏。 HTH

0

很多答案都說你做了一個基類函數virtual,這通常是完成但不需要的。你可以只執行下列操作...

class A{ 
public: 
void foo(); 
} 
class B: public A{ 
public: 
void foo(); 
} 
class C: public A{ 
public: 
void foo(); 
} 

如果你有一個指針如A* basePTR[2]可以將背景basePTR[0]作爲B然後basePTR[1]實例爲C實例的數組。但如果你想打電話basePTR[0]->foo()你會打電話給A::foo()

如果定義A

class A{ 
public: 
virtual void foo(); 
} 

然後調用basePTR[0]->foo()將調用B::foo()

他們是間接使用此功能在運行時的樣子必須完成以查看您是否調用基本函數foo()或派生類的foo(),但通常情況下,此功能值得相對較小的性能影響。

您可以定義A作爲

class A{ 
public: 
virtual void foo() =0; 
} 

=0foo()末意味着該函數是純虛函數,這意味着它必須由一個派生類中定義的,您不能做一個A的實例。一個很好的例子是你會在遊戲中使用它,你可能有一個基類GameToken,它有一個XYZ位置和一個純虛函數的繪製和更新。從這個你可以得到playerAIdynamicObject等...您的發動機則可以只存儲GameToken*類型的一個陣列,通過這個陣列,呼籲所有不同類型的數組中draw()update()迭代

+0

'虛擬'是需要的,因爲C#*中的覆蓋*表示*多態 – 2010-11-11 18:18:24