2013-04-16 110 views
2

以下測試代碼似乎表明,如果某個類具有兩個具有常見純虛方法的抽象基類,則這些方法在派生類中是「共享的」。抽象基類,多重繼承和常見純虛方法

#include <iostream> 
#include <string> 

using namespace std; 

struct A 
{ 
    virtual string do_a() const = 0; 
    virtual void set_foo(int x) = 0; 
    virtual int get_foo() const = 0; 
    virtual ~A() {} 
}; 

struct B 
{ 
    virtual string do_b() const = 0; 
    virtual void set_foo(int x) = 0; 
    virtual int get_foo() const = 0; 
    virtual ~B() {} 
}; 

struct C : public A, public B 
{ 
    C() : foo(0) {} 
    string do_a() const { return "A"; } 
    string do_b() const { return "B"; } 
    void set_foo(int x) { foo = x; } 
    int get_foo() const { return foo; } 
    int foo; 
}; 

int main() 
{ 
    C c; 
    A& a = c; 
    B& b = c; 
    c.set_foo(1); 
    cout << a.do_a() << a.get_foo() << endl; 
    cout << b.do_b() << b.get_foo() << endl; 
    cout << c.do_a() << c.do_b() << c.get_foo() << endl; 
    a.set_foo(2); 
    cout << a.do_a() << a.get_foo() << endl; 
    cout << b.do_b() << b.get_foo() << endl; 
    cout << c.do_a() << c.do_b() << c.get_foo() << endl; 
    b.set_foo(3); 
    cout << a.do_a() << a.get_foo() << endl; 
    cout << b.do_b() << b.get_foo() << endl; 
    cout << c.do_a() << c.do_b() << c.get_foo() << endl; 
} 

此代碼完全編譯以g ++ 4.1.2(誠然舊),使用-std = C++ 98 -pedantic -Wall -Wextra -Werror。輸出是:

A1 
B1 
AB1 
A2 
B2 
AB2 
A3 
B3 
AB3 

這是我的願望,但我質疑這是普遍的工作,還是隻是「偶然」。從根本上說,這是我的問題:我可以依賴這種行爲,還是應該始終從這種類型的場景的虛擬基類繼承?

+0

這確實是C++的工作方式。你可以依靠它,即使我個人覺得這個有危險的混淆(就像任何與多重繼承有關的事情,但這只是我,有時我們沒有任何選擇......)。 – syam

+0

這是一個合適的C++編譯器的基本行爲。這與舊的或較新的編譯器相同。 :-) – iammilind

+0

@syam熟悉術語「最終覆蓋」,並查看標準中的第10.3節。可能會照顧一些混亂。 –

回答

3

不要讓它比現在更難。與基類中的虛函數具有相同簽名的函數將覆蓋基本版本。無論你有多少基地,或者另一個基地是否具有相同簽名的虛擬功能都無關緊要。所以,是的,這是有效的。