C++ subclass inheritance - c++

Ok, this might be silly question but I can't figure out how to fix my problem.
Let's assume we have 4 classes
class A is a Base class
class B is derived from A with new methods (no override)
class C is derived from A
class D is derived from B (and also from A for inheritance)
my question is: how do I use a method defined in B in D?
If D inherit from B I get "error: member 'xxx' found in multiple base classes of different types"
if D does not inherit from B I get "use of undeclared identifier"

Here's how it's done - based on your description:
class A {
protected:
void foo();
};
class B : public A {
protected:
void bar();
};
class D : public B {
protected:
void baz() { B::bar(); }
};
Note that you should not have D inherit from A directly, except in very specific and rare cases. Inheritance is transitive.
Also, next time, Please post a Minimal, Complete, and Verifiable example and don't make us guess what you mean exactly.
In those cases in which the same method is available from the same subclasses from multiple inheritance paths are the "Diamond Pattern", and you can read about it here.

Related

C++ Diamond of Doom with external SDK

I have this annoying multiple-inheritance diamond of doom with a complicated twist (We're talking about MS COM objects, a detail which will be relevant later) -
Assume an abstract class (interface) A which has some pure virtual methods.
Another abstract class (another interface) B is derived from A and expands it with more pure virtual methods.
Class C is derived from class A and implements all of its abstract methods.
Class D is currently derived from class B, implementing all abstract methods from both A and B.
Right now I have two classes C, D with a lot of copy-pasted code (since most of the required interface resides in class A). I'd like to avoid this by having D inherit from C, however D also inherits from B, which creates a classic diamond of doom issue.
I know this can be solved with virtual inheritance, but here's the twist in the plot: Classes A and B are COM interfaces, defined in an SDK which I cannot modify (i.e. "A.h" and "B.h" are read only). The inheritance from A to B is not virtual and this cannot be modified. I can modify classes C and D, but they must completely adhere to the defined interfaces.
I'd appreciate any creative ideas on how to overcome this.
I'm assuming from the details of the question, that the problem you have is with the functions and not with some member variables of A (which seems to be just an interface).
In that case here are two options that spring to mind.
1) have D own a C rather than inherit from it.
class D : public B
{
public:
virtual int FA()
{
return m_c.FA();
}
private: C m_c;
};
or inherit privately from C
class D : public B, private C
{
public:
virtual int FA()
{
return C::FA();
}
};
Where FA() is some pure virtual function in A
Both cases involve defining a function to implement FA in D, but the actual implementation detail is not duplicated.
The ATL way of resolving this situation:
template <typename Itf>
class IAImpl : public Itf {
// Implement IA methods
};
class C : public IAImpl<IA> {};
class D : public IAImpl<IB> {
// Implement methods of IB that are in addition to IA.
};

More methods in derived classes than base class

I would like to ask a question about programming style in this case of derived class:
class A
{
public:
virtual foo1()=0;
}
class B: public A
{
public:
virtual foo1();
virtual foo2();
}
class C: public A
{
public:
virtual foo1();
}
int main() {
B mB();
C mC();
mB.foo2() //OK!
mC.foo2() // obviously, it is not correct
return 0;}
Therefore, should a derived class have less or equal public methods than the abstract base class?
If the derived classes require more methods, should these be private?
Derived classes will almost always have more public functions than base classes. This is the point of inheritance: you can define an abstract base class which only outlines the basic behavior of a variable, then derived classes can expand upon this basic behavior for specific cases.
An inherited class is always a specialization of the base class. It implements more specific functions (and usually more functions all together). In you're example, you're expecting two different specializations to behave the same way outside of the behavior defined by the base class. (foo2 is not defined in A). That's where the problem lies. If you need to define common behavior outside of A, the solution would be to create an intermediate class.
class Intermediate : public A
{
public:
virtual foo1()=0;
virtual foo2()=0;
}
class B: public Intermediate
{
public:
virtual foo1();
virtual foo2();
}
Now any class which can implement foo2 should extend Intermediate, and any function which requires functionality foo2 should ask for a variable with at least type Intermediate.
There is nothing wrong with this class structure. There is nothing wrong with a derived class having more methods than the parent class-- it's quite commonplace. The line mC.foo2(); is just wrong, and that is not the fault of the classes.
A derived class must at least implement ALL abstract methods from the base class. This is the minimum. If you do add other methods, members or whatever is up to you.
But it would be not very smart to derive from the class and add nothing, because this is not what inheritance is for (at least IS-A-relationships). If you go for private inheritance it might be different.
In nearly ALL projects I've worked on, we have had baseclasses that have less functionality than the derived class - in extreme cases, the baseclass may even just have nearly no functionality, but the derived class has dozens of functions and a half a dozen member variables.
This is exactly what derived classes are meant to do.
Obviously, you need to KNOW what kind of derived class you have, and only use the derived classes "extra" functions when they are available.

Ambiguity in multiple inheritance of interfaces in C++

I made a test code as following:
#include <iostream>
using namespace std;
#ifndef interface
#define interface struct
#endif
interface Base
{
virtual void funcBase() = 0;
};
interface Derived1 : public Base
{
virtual void funcDerived1() = 0;
};
interface Derived2 : public Base
{
virtual void funcDerived2() = 0;
};
interface DDerived : public Derived1, public Derived2
{
virtual void funcDDerived() = 0;
};
class Implementation : public DDerived
{
public:
void funcBase() { cout << "base" << endl; }
void funcDerived1() { cout << "derived1" << endl; }
void funcDerived2() { cout << "derived2" << endl; }
void funcDDerived() { cout << "dderived" << endl; }
};
int main()
{
DDerived *pObject = new Implementation;
pObject->funcBase();
return 0;
}
The reason I wrote this code is to test if the function funcBase() can be called in an instance of DDerived or not. My C++ complier (Visual Studio 2010) gave me a compile error message when I tried to compile this code. In my opinion, there is no problem in this code because it is certain that the function funcBase() will be implemented (thus overriden) in some derived class of the interface DDerived, because it is pure virtual. In other words, any pointer variable of type Implementation * should be associated with an instance of a class deriving Implentation and overriding the function funcBase().
My question is, why the compiler give me such an error message? Why the C++ syntax is defined like that; i.e., to treat this case as an error? How can I make the code runs? I want to allow multiple inheritance of interfaces. Of course, if I use "virtual public" or re-declare the function funcBase() in Implementation like
interface DDerived : public Derived1, public Derived2
{
virtual void funcBase() = 0;
virtual void funcDDerived() = 0;
};
then everything runs with no problem.
But I don't want to do that and looking for more convenient method, because virtual inheritance may degrade the performance, and re-declaration is so tedious to do if inheritance relations of classes are very complex. Is there any methods to enable multiple inheritance of interfaces in C++ other than using virtual inheritance?
As you've defined it, your object structure looks like this:
The important point here is that each instance of Implementation contains two entirely separate instances of Base. You're providing an override of Base::funcBase, but it doesn't know whether you're trying to override funcBase for the Base you inherited through Derived1, or the Base you inherited through Derived2.
Yes, the clean way to deal with this is virtual inheritance. This will change your structure so there's only one instance of Base:
This is almost undoubtedly what you really want. Yes, it got a reputation for performance problems in the days of primitive compilers and 25 MHz 486's and such. With a modern compiler and processor, you're unlikely to encounter a problem.
Another possibility would be some sort of template-based alternative, but that tends to pervade the rest of your code -- i.e., instead of passing a Base *, you write a template that will work with anything that provides functions A, B, and C, then pass (the equivalent of) Implementation as a template parameter.
The C++ language is designed in such a way that in your first approach without virtual inheritance there will be two parent copies of the method and it can't figure out which one to call.
Virtual inheritance is the C++ solution to inheriting the same function from multiple bases, so I would suggest just using that approach.
Alternately have you considered just not inheriting the same function from multiple bases? Do you really have a derived class that you need to be able to treat as Derived1 or Derived2 OR Base depending on the context?
In this case elaborating on a concrete problem rather than a contrived example may help provide a better design.
DDerived *pObject = new Implementation;
pObject->funcBase();
This creates a pointer of type DDerived to a Implementation. When you are using DDerived you really just have a pointer to an interface.
DDerived does not know about the implementation of funcBase because of the ambiguity of having funcBase being defined in both Derived1 and Derived2.
This has created a inheritance diamond which is what is really causing the problem.
http://en.wikipedia.org/wiki/Diamond_problem
I also had to check on the interface "keyword" you have in there
it's an ms-specific extension that's recognised by visual studio
I think C++ Standard 10.1.4 - 10.1.5 can help you to understand the problem in your code.
class L { public: int next; /∗ ... ∗/ };
class A : public L { /∗...∗/ };
class B : public L { /∗...∗/ };
class C : public A, public B { void f(); /∗ ... ∗/ };
10.1.4 A base class specifier that does not contain the keyword virtual,
specifies a non-virtual base class. A base class specifier that
contains the keyword virtual, specifies a virtual base class. For each
distinct occurrence of a non-virtual base class in the class lattice
of the most derived class, the most derived object (1.8) shall contain
a corresponding distinct base class subobject of that type. For each
distinct base class that is specified virtual, the most derived object
shall contain a single base class subobject of that type. [ Example:
for an object of class type C, each distinct occurrence of a
(non-virtual) base class L in the class lattice of C corresponds
one-to-one with a distinct L subobject within the object of type C.
Given the class C defined above, an object of class C will have two
subobjects of class L as shown below.
10.1.5 In such lattices, explicit qualification can be used to specify which
subobject is meant. The body of function C::f could refer to the
member next of each L subobject: void C::f() { A::next = B::next; } //
well-formed. Without the A:: or B:: qualifiers, the definition of C::f
above would be ill-formed because of ambiguity
So just add qualifiers when calling pObject->funcBase() or solve ambiguity in another way.
pObject->Derived1::funcBase();
Updated: Also very helpful reading will be 10.3 Virtual Functions of Standard.
Have a nice weekend :)

Multiple Inheritance with abstract and defined inherited functions of the same name

First off I apologize if there is another post out there that answers this, all the similar posts I found dealt with diamond inheritance schemes or defined functions, which this does not.
In short, I'm wondering if it is possible to have one class inherit from two other classes where both child classes has a function with the same name and arguments but it is defined in one child class, and pure-virtual in another. Furthermore if I can do this, would invoking the function on the pure-virtual/abstract class end up calling the defined function on the other child class with minimal changes to the derived class?
Example:
class A
{
public:
virtual void Set(int X) = 0;
};
class B
{
public:
virtual void Set(int X);
};
class AB : public A, public B
{
//other methods not relevant to example go here
};
int main(int argc, char **argv)
{
int Y = 5;
A* ObjectA = new AB();
ObjectA->Set(Y);
return 0;
}
So far my attempts to compile this basic example have been met with errors that say:
'AB' : cannot instantiate abstract class
due to following members:
'void A::Set(int)' : is abstract
When doing my own research I couldn't find a clear answer, but based on other questions that dealt with related topics I found that using a "using B::Set" in class AB may help with this. But when I try adding it to the AB class definition, the error persists.
Is there any way I can make this work?
If you had 2 normal functions Set in A and B, then using B::Set would tell the compiler that if you have object of class AB and call method Set of that object, B::Set will be invoked, if AB::Set not defined explicitly.
Your situation is different. You have pure virtual function A::Set that leads A to be abstract class. As AB does not override A::Set, AB becomes abstract too, that is why you cannot instantiate it.
What you can do here
You can implement AB::set to call B::Set:
class AB : public A, public B
{
public:
void Set(int x) { return B::Set(x); }
};
Also I do not recommend same method names for base classes, as I do not recommend multiple inheritance, try use aggregation instead.
Have you tried implementing the method:
class AB : public A, public B
{
void Set(int X) {}
};
The reason it's not working is that A::Set() is pure virtual. I.e. it has no implementation. But you try to call it. You have to override it in the derived class in order to be able to instantiate the derived class.
The using doesn't work in your case because you have an A*, so there's no ambiguity for the compiler.
In case you had:
AB* ObjectA = new AB();
ObjectA->Set(Y);
you'd have to use using inside the declaration of AB to resolve the ambiguity.
Class AB derives from A, A has a pure virtual method making the class abstract, AB must implement any pure virtual methods declared in a base class in order to be instantiated.
I would try to avoid multiple inheritance it can cause many headaches and there are generally better ways to solve a problem, for instance in this example I don't understand the point in deriving from both A and B, if B shares and in fact implements the same interface as A then surely B should be derived from A.

Virtual Inheritance Confusion

I'm reading about inheritance and I have a major issue that I haven't been able to solve for hours:
Given a class Bar is a class with virtual functions,
class Bar
{
virtual void Cook();
};
What is the different between:
class Foo : public Bar
{
virtual void Cook();
};
and
class Foo : public virtual Bar
{
virtual void Cook();
};
? Hours of Googling and reading came up with lots of information about its uses, but none actually tell me what the difference between the two are, and just confuse me more.
Functionality wise there is not much difference between the 2 versions. With the case of virtual inheritance, every implementation generally adds a (vptr like) pointer (same as in the case of virtual functions). Which helps to avoid multiple base class copies generated due to multiple inheritance (the diamond inheritance problem)
Also, virtual inheritance delegates the right to call the constructor of its base class. For example,
class Bar;
class Foo : public virtual Bar
class Other : public Foo // <--- one more level child class
So, now Bar::Bar() will be called directly from Other::Other() and also will be placed at the first place among other base classes.
This delegation feature helps in implementing a final class (in Java) functionality in C++03:
class Final {
Final() {}
friend class LastClass;
};
class LastClass : virtual Final { // <--- 'LastClass' is not derivable
...
};
class Child : public LastClass { // <--- not possible to have object of 'Child'
};
Virtual inheritance is only relevant if classes are to inherit from
Foo. If I define the following:
class B {};
class L : virtual public B {};
class R : virtual public B {};
class D : public L, public R {};
Then the final object will only contain one copy of B, shared by both
L and R. Without the virtual, an object of type D would contain
two copies of B, one in L, and one in R.
There is some argument that all inheritance should be virtual (because
in the cases where it makes a difference, that is what you want most of
the time). In practice, however, virtual inheritance is expensive, and
in most cases, not necessary: in a well designed system, most
inheritance will simply be of a concrete class inheriting from one or
more "interfaces"; such a concrete class is usually not designed to be
derived from itself, so there is no problem. But there are important
exceptions: if, for example, you define an interface, and then
extensions to the interface, the extensions should inherit virtually
from the base interface, since a concrete implementation could want to
implement several extensions. Or if you are designing mixins, where
certain classes only implement part of the interface, and the final
class inherits from several of these classes (one per part of the
interface). In the end, the criteron as to whether to inherit virtually
or not isn't too difficult:
if the inheritance isn't public, it probably shouldn't be virtual
(I've never seen an exception), otherwise
if the class is not designed to be a base class, there's no need for
virtual inheritance, otherwise
the inheritance should be virtual.
There are a few exceptions, but the above rules err on the side of
safety; it's usually "correct" to inherit virtually even in cases where
the virtual inheritance isn't necessary.
One final point: a virtual base must always be initialized by the most
derived class, not the class that directly inherits (and declares that
the inheritance is virtual). In practice, however, this is a non-issue.
If you look at the cases where virtual inheritance makes sense, it is
always a case of inheriting from an interface, which will contain no
data, and thus have (only) a default constructor. If you find yourself
inheriting virtually from classes with constructors which take
arguments, it's time to ask some serious questions about the design.
In this case, no difference. Virtual inheritance is related to sharing superclass subobjects instances by derived classes
struct A
{
int a;
};
struct B : public virtual A
{
int b;
}
struct C : public virtual A
{
int c;
};
struct D : public B, public C
{
};
There's a single copy of the member variable a in the instance of D; If A was not a virtual base class, there would be two A subobjects in instance of D.
Virtual function is a function that will probably have different implementation in derived class (although it's not a must).
In your last example is virtual inheritance. Imagine a case where you have two classes (A and B) derived from a base class (let's call it 'Base'). Now imagine a third class C derived from A and B. Without virtual inheritance, the C would contain two copies of 'Base'. That could lead to ambiguity while compiling. The important thing in virtual inheritance is that the parameters for the 'Base' class constructor (if any) MUST be provided in the class C, because such calls from A and B will be ignored.