2009-01-22 52 views
10

以下代碼會生成警告C4250。我的問題是,最好的解決方案是什麼?Visual Studio編譯器警告C4250('class1':通過優勢繼承'class2 :: member')

class A 
{ 
    virtual void func1(); 
} 

class B : public A 
{ 
} 

class C : public A 
{ 
    virtual void func1(); 
} 

class D : public B, public C 
{ 
} 

int main() 
{ 
    D d; 
    d.func1(); // Causes warning 
} 

據我讀過應該有可能做到這一點:

class D : public B, public C 
{ 
    using B::func1(); 
} 

但是,這實際上並沒有做任何事情。我目前解決它的方式是:

class D : public B, public C 
{ 
    virtual void func1() { B::func1(); } 
} 

大家對此的看法是什麼?

+0

第一個塊中的代碼不會編譯,並且在將其更改爲編譯後,它不會生成C4250。 – quamrana 2010-02-03 08:53:53

回答

7

您是否嘗試從類A繼承公共虛擬?我認爲它應該解決它。


    class B :public virtual A; 
    class C :public virtual A; 
    class D : public virtual B, public virtual C; 

虛擬繼承假設解決歧義。

+1

是的,即使使用虛擬繼承,它仍然存在相同的問題(有兩個合適的函數可供調用,編譯器只是選擇最「被覆蓋」的那一個) – 2009-01-22 15:48:25

+0

然後我想你的建議解決方案是無法逃脫的。 – 2009-01-22 15:49:32

0

我認爲您使用的解決方案可能是要走的路,遺憾地說。我能想到的唯一可能的幫助就是如果你能夠使A的func1純虛擬。但是,在你的真實程序中這可能是不可行的。

18

我有下面的代碼相同的警告:

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

class Implementation : public virtual Interface 
{ 
public: 
    virtual void A() {}; 
}; 

class ExtendedInterface : public virtual Interface 
{ 
    virtual void B() = 0; 
}; 

class ExtendedImplementation : public ExtendedInterface , public Implementation 
{ 
public: 
    virtual void B() {}; 
}; 

bug report爲Visual C++ 2005中的MSDN表明,這是一個已知的bug,它被認爲是不夠的重要修復......他們建議在這種情況下通過使用編譯指示禁用警告。我認爲你的情況也是安全的,但你應該使用虛擬繼承,如Gal Goldman的答案所示。

0

容易解決

class A 
{ 
    virtual void func1(); 
} 

class B : public A 
{ 
} 

class C : public A 
{ 
    virtual void func1(); 
} 

class D : public B, public C 
{ 
    virtual void func1() 
    { 
    C::func1(); 
    } 
} 

int main() 
{ 
    D d; 
    d.func1(); // Causes warning 
} 
1

[註釋真的,但我沒有足夠的代表...]

大衛Segonds VS 2005中確定這是一個已知的bug,剛剛試過他的例子代碼在VS 2008中,它展現了同樣的問題。