我现在正在VS2010中学习C ++编程中的OO。我在C ++中遇到了一些基本的继承问题。这是我的代码:
问题1:
class bs
{
public:
int a;
virtual void name(){};
};
class A:virtual public bs
{
public:
int a;
virtual void name(){};
};
class B:virtual public bs
{
public:
int a;
virtual void name(){};
};
class D:virtual public bs
{
public:
int a;
virtual void name(){};
};
class C:public A,public B,public D
{
};
编译器给出了错误C2250。当我从每个类中删除虚拟继承时。即。
class bs
{
public:
int a;
virtual void name(){};
};
class A:public bs
{
public:
int a;
virtual void name(){};
};
class B:public bs
{
public:
int a;
virtual void name(){};
};
class D:public bs
{
public:
int a;
virtual void name(){};
};
class C:public A,public B,public D
{
};
它生效了。另外,如果我在错误代码中重写C类中的virtual void name(){};
,那么编译器就会顺利进行。所以我的问题是为什么有必要强制在虚拟继承情况下重写虚函数,而不必在非虚函数中重写虚函数继承情况。
问题2:
如上面的代码,我想在非虚拟继承情况下添加bs *mybs = new C();
class bs
{
public:
int a;
virtual void name(){};
};
class A:public bs
{
public:
int a;
virtual void name(){};
};
class B:public bs
{
public:
int a;
virtual void name(){};
};
class D:public bs
{
public:
int a;
virtual void name(){};
};
class C:public A,public B,public D
{
virtual void name(){};
};
//bs *mybs = new C(); //C2594
编译器说错误C2594。但是在虚拟继承情况下,编译器没有错误。
class bs
{
public:
int a;
virtual void name(){};
};
class A:virtual public bs
{
public:
int a;
virtual void name(){};
};
class B:virtual public bs
{
public:
int a;
virtual void name(){};
};
class D:virtual public bs
{
public:
int a;
virtual void name(){};
};
class C:public A,public B,public D
{
virtual void name(){};
};
bs *mybs = new C();//It is OK
虚拟继承情况有什么问题?
我认为这两个问题并不难,但在C ++中是基本的。但是,我不熟悉C ++版本中的OO。感谢您解决问题。
答案 0 :(得分:1)
Q1:给定虚拟继承,派生类只获取bs
对象的一个实例,但有name()
的三个实现,并且它不知道使用哪个。如果你非虚拟地导出,则在A,B和D类中嵌入三个bs基,每个基都可以覆盖实现。或者,您已经发现可以使用C中的一个实现替换虚拟继承之后的模糊实现。
Q2:在非虚拟情况下,嵌入的A,B和D对象中有三个bs
个基数:您希望指向哪一个?这是不明确的,所以你得到错误。如果您使用了虚拟继承,那么只有一个bs
基础对象,您可以获得指向它的指针。
举例说明:
VIRTUAL NON-VIRTUAL
. bs bs bs bs
. / | \ | | |
. A B D A B D
. \ | / \ | /
. C C
在左侧,您的问题C
不知道要使用A::name()
,B::name()
或D::name()
中的哪一个,除非您覆盖了{{1}中的所有三个}。
在右侧,您的问题是C
不知道指向哪个b* my_b_ptr
基地。