I have a base class 'Base', which is a pure virtual class:
class Base {
public:
virtual void A() = 0;
virtual void B() = 0;
virtual ~Base() { } // Eclipse complains that a class with virtual members must have virtual destructor
};
I also have 2 other classes, one of them implements A() and the other one implements B():
class DerivedA : public virtual Base
{
public:
virtual void A() {
printf("Hello from A");
}
};
class DerivedB : public virtual Base
{
public:
virtual void B() {
printf("Hello from B");
}
};
The virtual keyword in the declaration should solve the diamond problem.
Now I would like to combine the two classes into another class, so that both A() and B() are implemented, like this:
class DerivedC: public DerivedA, public DerivedB {
// Now DerivedA and DerivedB are combined
};
// Somewhere else in the code
DerivedC c;
c.A();
c.B();
The problem:
Even though G++ compiles the code just fine, Eclipse gives an error: The type 'DerivedC' must implement the inherited pure virtual method 'Base::B'
.
When compiling with visual studio, I get 2 warnings:
warning C4250: 'DerivedC' : inherits 'DerivedB::DerivedB::B' via dominance
warning C4250: 'DerivedC' : inherits 'DerivedA::DerivedA::A' via dominance
So the question is: what is the correct way of doing this? Does the code above produce undefined behavior?
Note: The title may be a little misleading, I have no idea what a good title for this question would be.
What is the correct way of doing this? Does the code above produce undefined behavior?
The code is perfectly valid. There is no Undefined Behavior here.
An unqualified call of A()
through a DerivedC
class object, will always call DerivedA::A()
, while an unqualified call of B()
through a DerivedC
class object, will always call the DerivedB::B()
instance.
Visual C++ gives you a warning because your code uses a less commonly known feature of virtual Inheritance which may not be obvious to most common users and might surprise them. In this case, the warning should be taken as an Informative Nitpick rather than a warning.
Note that the C++ Standard does not restrict compilers from emitting informative warnings for perfectly valid code. The documentation for warning C4250 gives an example which tells you why visual C++ chooses to give this warning.
You might want to try this :
class DerivedC: public DerivedA, public DerivedB {
public:
using DerivedA::A;
using DerivedB::B;
};
I can't test with Eclipse or VC++ myself...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With