Why doesn't this code work? (C ++ OOP) public inherits

I would like some help to explain this phenomenon:

#include <iostream>
using namespace std;

class A
{
public:
    void m() {cout<<"A::m "<<this<<endl;};
};

class B1:  public A
{
public:
    void m() {cout<<"B::m "<<this<<endl;};
};

class B2:  public A ,public B1
{
};

class D : public B2
{};

int main()
{
    B2 b;
    D d;
    A* a = &b; // Row 27
    //error: a = &d;  Base class 'A' is ambiguous // Row 28
    return 0;
}

      

Why does the code in Row27 work, but the code in Row28 does not? Thanks in advance!

Note: I am well aware of virtual inheritance, I just want to know what is the difference between Row27 and Row28 - why throw a compile error when the other is not?

+3


source to share


2 answers


Because you are using non-virtual inheritance for inference A

, that indirectly creates two sub-type objects A

in each type object D

. The compiler is unable to resolve which sub-sequential object you are referencing when performing a pointer-to-output conversion to a pointer-to-base conversion and throws an error.

To have only one type sub-object A

generated for type objects D

, you must make inheritance A

virtual by inheritance paths that D

infer fromA

class B1:  virtual public A
{
    // ...
};

class B2:  virtual public A, public B1
{
};

      

EDIT:



I tried to compile your example in Visual Studio 2010 SP1 which gives me a warning about the definition B2

:

class B2: public A, public B1
{
};

1>sotest.cpp(18): warning C4584: 'B2' : base-class 'A' is already a base-class of 'B1'
1>          sotest.cpp(6) : see declaration of 'A'
1>          sotest.cpp(11) : see declaration of 'B1'

      

In other words, for some reason VC10 seems to consider inheritance from A

redundant and ignore it. That's why compilation A* a = &b;

: class B2

inherits from A

only once (through B1

). The same does not apply to D

, because VC10 probably does not have redundant inheritance to ignore, but D

effectively inherits from A

twice (through B1

and through B2

).

I ignore the reasons why VC10 behaves this way, and I don't know if there is a compiler option to suppress this behavior. Notably, both GCC 4.7.2 and Clang 3.2 refuse to compile assignments A* a = &b;

.

+1


source


For future users, this looks like:

I just tried this on GCC 4.7.1 and Clang 3.2 and I get a compiler error if I don't use virtual inheritance. which compiler are you using? - Andy Prowl



VS2010 does compile, but throws a warning that suggests it ignores B2 inheritance from A. This is why Row 27 works. I think this is a strange behavior of VS2010 and I don't know if there is any way to disable it (other than looking at all warnings as errors) - Andy Prowl

Thank you @ Andy Prowl.

+1


source







All Articles