2009-01-27 92 views
3

比方說,我們有純虛擬方法覆蓋(規則)虛擬方法的效果如何?

class A {  
public:  
    virtual int foo() { cout << "foo!"; }  
} 

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

class C : public B { 
public: 
    virtual int foo() { cout << "moo!"; } 
} 

這真的是覆蓋?我想這實際上是超載。 製作類似這樣的設計的意義是什麼?

我們得到了一個基類A.然後,我們這是從具體類派生的一個抽象的派生類B,然後通過C的實現B的

什麼是我們在這裏做是否使任何意義?

回答

1

在我看來,純虛擬方法的唯一影響是讓B成爲抽象類。

1

它仍然是壓倒一切的,因爲當你有A*類型的指針pC類的實例,p->foo()還叫C::foo()

也許,設計師要插入層次結構中的一個抽象類,從一些具體的類派生,並強制在子類中重寫該方法。我不認爲這是非常明智的。

3

重載意味着您​​有兩個具有相同名稱但具有不同參數的函數。情況並非如此。

實施例:

int functionA() { /*...*/ }; 
int functionA(int someParameter) { /*...*/ }; 

重寫裝置重寫與在子類中的相同參數的函數。這就是你作爲一個例子提出的。

這就是定義的一部分。現在進行設計:

當你有一個純虛函數時,具體的子類必須覆蓋它。因此,通過添加純虛函數,確保所有子類都提供相同的函數集(= interface)。這在示例代碼中似乎就是這種情況。

但它不是一個很好的例子,因爲具體的超類已經實現了foo()的默認功能。當有一個抽象的子類將其重新定義爲純粹的虛擬類時,這對我來說是類的層次結構有缺陷的標誌,因爲子類(以及foo()的調用者)通常應該能夠回退到默認實現。用這樣一個抽象的例子來解釋有點難,但像這樣的層次結構對我來說有點懷疑。

+0

是的,它看起來「可疑」,但我不會說它本身就是一個缺陷,也許在現實世界的代碼中它是有意義的。順便說一句,+1,因爲你是唯一一個回答超載/壓倒性部分:) – 2009-01-27 13:12:37

1

你是說從B派生的類必須實現int foo();。你可能想要這樣做來迫使其他程序員去考慮他們想如何讓foo()行爲,但我認爲這是一個壞主意 - 實際上他們很可能通過調用來實現A :: foo( )

如果你只是想讓B抽象,給它一個純粹的虛擬析構函數 - 你還需要提供一個析構函數的實現,以避免鏈接錯誤。