0

这些天我在 VS2010 中学习 C++ 编程中的 OO。我在 C++ 中遇到了一些基本的继承问题。这是我的代码:

问题一:

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。当我从每个类中删除虚拟继承时。IE

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(){};错误代码中的类C,编译器运行良好。所以我的问题是为什么在虚拟继承情况下必须强制重写虚函数,而在非虚拟继承情况下则不需要。

问题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 并不熟悉。感谢您解决问题。

4

1 回答 1

1

Q1:给定虚拟继承,派生类只得到bs对象的一个​​实例,却有3个实现name(),不知道用哪一个。如果非虚拟派生,则在 A、B 和 D 类中嵌入了三个 bs 基,每个基都可以覆盖实现。或者,您发现可以用 C 中的一种实现替换虚拟继承之后的模棱两可的实现。

Q2:在非虚拟的情况下,你bs在嵌入的 A、B、D 对象中有 3 个基:你要指针指向其中的哪一个?这是模棱两可的,所以你得到了错误。如果您使用虚拟继承,那么只有一个bs基础对象,您可以获得指向它的指针。

为了显示:

 VIRTUAL            NON-VIRTUAL
 .       bs          bs  bs  bs
 .     /  |  \       |   |   |
 .     A  B  D       A   B   D
 .     \  |  /        \  |  /
 .        C              C

在左边,你的问题是C不知道使用哪一个A::name()B::name()或者D::name()使用,除非你覆盖了所有三个C

在右边,你的问题是b* my_b_ptr不知道bs指向哪个基地。

于 2013-05-08T07:07:00.033 回答