Filling out abstract class members by deriving from concrete class - c++

Let's say I have an interface that inherits from another interface (pure abstract class)
class BaseInterface
{};
Then another interface builds upon BaseInterface
class ExtendedInterface : public BaseInterface
{};
Now, I have a concrete class that implements BaseInterface:
class Base : public BaseInterface
{};
Now, I want to implement ExtendedInterface, but since I already have Base I want to fill out the BaseInterface members with base. E.g.:
class Extended : public ExtendedInterface, public Base
{};
This doesn't seem to work. I get complaints that I cannot instantiate extended since it is an abstract class. The only way I can get it to work is by using virtual inheritance, but then I get compiler warnings about inheriting via dominance.

What's the problem ?
With your multiple inheritance, Extended inherits two times from BaseInterface. This means that there are two independent BaseInterface subobjects:
one is inherited via the concrete Base class, which has overridden all the pure virtual functions.
but the other is inherited via ExtendedInterface class, which is still abstract.
In consequence, as some subobjects of Extended still have pure virtual functions, your class is still an abstract class that can't be instantiated.
How to solve it ?
As despite the multiple inheritance you apparently expect to have only one BaseInterface, you need to use virtual inheritance:
class BaseInterface
{ virtual void test()=0; }; // abstract class
class ExtendedInterface : public virtual BaseInterface // virtual inheritance
{}; // abstract class
class Base : public virtual BaseInterface // virtual inheritance
{ void test() override {} }; // concrete class
class Extended : public ExtendedInterface, public Base // multiple
{}; // thanks to virtual inheritance, concerete class
With this logic, there will be only one BaseInterface in Extended, with virtual functions overridden, and you can instantiate it.
Here an online demo

Related

Protected Constructor in multilevel virtual inheritance in C++

How is the folloing code working? MakeFinal constructor is protected, so it should not be accessible to FinalUser class. But I didn't get any build or execution error.
class MakeFinal
{
protected:
MakeFinal(void) {};
public:
~MakeFinal(void) {};
};
class Final : virtual public MakeFinal
{
public:
Final(void) {};
~Final(void) {};
};
class FinalUser : public Final
{
public:
FinalUser(void) {};
~FinalUser(void) {};
};
int main()
{
FinalUser *finalUserHeap_ = new FinalUser();
return 0;
}
A virtual base class is initialized by the single most derived class' constructor's member initializer list.
Because the virtual base can be a common base-class object for multiple derived classes, and the initializations specified by those derived classes can conflict.
The initialization specification in the most derived class acts conceptually as if the most derived class was derived directly from the virtual base class, i.e.
FinalUser(void) {};
… is equivalent to
FinalUser(): MakeFinal() {}
Since the MakeFinal constructor is protected, it's available to all derived classes.
That includes that it's available to class FinalUser.
In other news:
The names in this code indicate that it's about using a C++03 trick for creating a class that can't be (usefully) derived from, a “final” class. The trick is essentially to have a class template that can act as most derived class and that has the necessary friend-ship to access the for other classes inaccessible constructor of the virtual base class. C++11 introduced the keyword final to do that more easily, and without the overhead of virtual inheritance.
You need to know the next:
If the inheritance is public, everything that is aware of Base and Child is also aware that Child inherits from Base.
If the inheritance is protected, only Child, and its children, are aware that they inherit from Base.
If the inheritance is private, no one other than Child is aware of the inheritance.
#Anzurio answer in Difference between private, public, and protected inheritance
According this. You need to use private if you want that FinalUser class donot have access to MakeFinal.
Derived classes have access to protected members of their base classes. That's the difference between protected and private.

How can I override a pure virtual method using a privately inherited method?

I have the following:
class Abstract
{
virtual void AbstractMethod() = 0;
};
class Implementer
{
void AbstractMethod() {};
};
class Concrete : public Abstract, private Implementer
{};
I cannot instantiate Concrete because the pure virtual method AbstractMethod is not overridden. What am I doing wrong?
You are using multiple inheritance here.
Concrete has two hierarchies treated separately:
Abstract and Implementer. Since Abstract has no relation to Implementer your use of virtual in that case (for sibling inheritance) will fail.
You need to override virtual functions in derived classes. You cannot do it in the manner you are attempting.
Specifically, if you were to re-write it as such it would work:
class Abstract
{
virtual void AbstractMethod() = 0;
};
class Implementer : private Abstract
{
void AbstractMethod() {};
};
class Concrete : public Implementer
{};
I would like to point out your use of public or private inheritance in Concrete does not affect the problem. If you change Implementer to public in your original example it would still fail to be a concrete class.
Useful Auxiliary Information: Avoid multiple inheritance when possible, favor composition over inheritance, and prefer shallow inheritance over deep. http://en.wikipedia.org/wiki/Composition_over_inheritance
If you are going through the route of multiple inheritance be aware of separate inheritance hierarchies being default in C++, and the need for virtual inheritance to combine the different paths (virtual methods still require a derived class to override them, not sibling classes though): http://en.wikipedia.org/wiki/Multiple_inheritance

Can an abstract class be implemented without pure virtual functions in C++?

I thought of using protected constructor, but it couldn't completely solve the purpose since the class inheriting from it would be able to instantiate the base class.
As for private constructor, the derived classes too would not be instantiated.
So, any suitable technique would be appreciated.
It is unclear what you are really asking for. So let me try to clear some points:
Pure virtual functions can have definitions
If your concern is that you want to provide definitions for all of the virtual functions in your base you can provide the definitions for the pure virtual functions, and they will be available for static dispatch.
Protected grants access to your base subobject, not to every instance of base
There is a common misconception that protected allows a particular derived type accessing any instance of base. That is not true. The keyword protected grants access to the base subobject within the derived type.
class base {
protected: base() {}
};
class derived : public base {
derived() : base() { // fine our subobject
base b; // error, `b` is not your subobject
}
};
The definition of an abstract class is one that has at least one pure virtual function (virtual function-signature = 0; You can't create an abstract class without them.
Can an abstract class be implemented without pure virtual functions in C++?
If you choose the point of view from Static Polymorphism, you can do that!
An abstract base class would be simply missing a default method implementation for an interface method from the deriving class.
Additionally you can use protected constructors for those CRTP base class templates, to require inheritance for instantiation.
UPDATE:
I found a nice slide show, that explains static vs dynamic polymorphism comprehensively. Each technique has it's pros and cons and certain fields of usage, additionally you can mix both techniques (wisely of course).
To elaborate a bit, I'll give a sample:
template<class Derived>
class AbstractBase
{
public:
// Equivalent for a pure virtual function
void foo()
{
// static_cast<> enforces an 'Is a' relation from Derived to AbstractBase
static_cast<Derived*>(this)->fooImpl();
}
// Equivalent for simple virtual function (overidable from Derived)
void bar()
{
static_cast<Derived*>(this)->barImpl();
}
// Default implementation for any call to bar()
void barImpl()
{
}
protected:
AbstractBase() {}
};
// Compilation will fail, since ConcreteClass1 doesn't provide
// a declaration for fooImpl()
class ConcreteClass1
: public AbstractBase<ConcreteClass1>
{
}
// Compiles fine
class ConcreteClass2
: public AbstractBase<ConcreteClass2>
{
public:
void fooImpl()
{
// Concrete implementation ...
}
}
The following sample shows that the pattern introduced above enforces an 'Is a' relationship between abstract class and inheriting class (the template parameter)
class ConcreteClass3
{
public:
void fooImpl()
{
// Concrete implementation ...
}
}
// Instantiation will fail, because
// * the constructor is protected
// * at least the static cast will fail
AbstractBase<ConcreteClass3> instance;
I read it in my book
An abstract class is a class that is designed to be specifically used as a base class. An abstract class contains at least one pure virtual function. You declare a pure virtual function by using a pure specifier (= 0) in the declaration of a virtual member function in the class declaration.

Interfaces in c++

I would like to use interfaces in c++ like in java or in c#. I decided to use purely abstract classes with multiple inheritance, but something is terribly wrong when I specialize the interface:
class Interface
{
public:
virtual int method() = 0;
};
// Default implementation.
class Base: virtual public Interface
{
public:
virtual int method() {return 27;}
};
// specialized interface
class Interface2: public Interface
{
public:
virtual int method() = 0;
// some other methods here
};
// concrete class - not specialised - OK
class Class: public virtual Interface, public virtual Base
{
};
// concrete class - specialised
class Class2: public Interface2, public Base
{
};
int main()
{
Class c;
Class2 c2;
return 0;
}
Warning 1 warning C4250: 'Class' : inherits 'Base::Base::method' via dominance 30
Error 2 error C2259: 'Class2' : cannot instantiate abstract class 42
What is the proper way to do this?
Class2 inherits from an abstract class (Interface2) but does not implement the pure virtual method, so it remains as an abstract class.
Heh heh, this problem tickles something buried deep in my head somewhere. I can't quite put my finger on it but I think it's to do with defining an interface heirarchy and then inheriting both an interface and an implementation. You then avoid having to implement all functions with by forwarding calls to a base class. I think.
I think this simple example shows the same thing, but is maybe a bit easier to understand because it uses things that can be easily visualized: (please forgive the struct laziness)
#include <iostream>
using namespace std;
struct Vehicle
{
virtual void Drive() = 0;
};
struct VehicleImp : virtual public Vehicle
{
virtual void Drive()
{
cout << "VehicleImp::Drive\n";
}
};
struct Tank : virtual public Vehicle
{
virtual void RotateTurret() = 0;
};
struct TankImp : public Tank, public VehicleImp
{
virtual void RotateTurret()
{
cout << "TankImp::RotateTurret\n";
}
// Could override Drive if we wanted
};
int _tmain(int argc, _TCHAR* argv[])
{
TankImp myTank;
myTank.Drive(); // VehicleImp::Drive
myTank.RotateTurret(); // TankImp::RotateTurret
return 0;
}
TankImp has essentially inherited the Tank interface and the Vehicle implementation.
Now, I'm pretty sure this is a well known and acceptable thing in OO circles (but I don't know if it has a fancy name), so the dreaded diamond thing is ok in this case, and you can safely suppress the dominance warning because it's what you want to happen in this case.
Hope that somehow helps point you in the right direction!
BTW, your code didn't compile because you hadn't implemented the pure virtual "method" in Class2.
EDIT:
Ok I think I understand your problem better now and I think the mistake is in Interface2. Try changing it to this:
// specialized interface
class Interface2: public virtual Interface // ADDED VIRTUAL
{
public:
//virtual int method() = 0; COMMENTED THIS OUT
// some other methods here
};
Interface2 should not have the pure virtual defintion of method, since that is already in Interface.
The inheritance of Interface needs to be virtual otherwise you will have an ambiguity with Base::method when you derive from Interface2 and Base in Class2.
Now you should find it will compile, possibly with dominance warnings, and when you call c2.method(), you get 27.
Based on this comment
If the method is not reimplemented in Class2 or Class (it is not in
this case) Base::method() will be called. Otherwise the reimplementation
will be called. There is an interface hierarchy with a common base
dumb implementation.
– danatel 16 mins ago
That's not what you got, you don't have a common base, you've got
Interface -> Interface2 -> Class2
Interface -> Base -> Class2
The interface is not 'merged' in the derivation tree, interface2 does not inherit virtually from interface, so it'll have its own interface super class.
It's like the pure virtual method() exists twice in Class2, once implemented via Class, and once not-implemented.
And even if you had inherited virtually, the common base (Interface) still would not have an implementation
If Base contains trivial operations that should be usuable in the whole hierarchy, then why not have Base as your startpoint? (even if still pure virtual with an implementation).
If this was just a very simple example to make the question short, something like the Bridge Pattern might be more usefull. But it's hard to guide you further without knowing more.
You should also look at defining a virtual destructor in your Interface if you might be deleting using an Interface or Base pointer.
Without a virtual destructor you will have problems if you do something like:
Base *b = new Class2();
delete b;
Regarding Class: All you need to do is derive Class from Base -- the fact that it implements Interface is implied, and in fact, inescapable:
class Class: public Base // virtual inheritance is unnecessary here
{
};
Class will inherit method() from Base as desired.
Regarding Class2:
Disclaimer: Negative result ahead
Based on your comment on Tom's answer, I thought I had the answer for Class2:
// concrete class - specialised
class Class2: public Interface2, public Base
{
public:
using Base::method; // "Imports" all members named "method" from Base
};
But actually, this doesn't work. Grovelling through the C++ standard reveals that
section 7.3.3, paragraph 14 explains that using can't be used to resolve ambiguous accesses to inherited members:
... [Note: because a using-declaration designates a base class member (and not a member subobject or a member function of a base class subobject), a using-declaration cannot be used to resolve inherited member ambiguities. ...]
It seems that the only way to get the desired behaviour in Class2 is to manually forward the method:
// concrete class - specialised
class Class2: public Interface2, public Base
{
public:
virtual int method() { return Base::method(); }
};
Regarding virtual inheritance: You don't need it for Class's declaration, but you probably do need it for Interface2's declaration to ensure that Class2 only has a single subobject of type Interface -- as it stands, every Class2 object has two subobjects of this type. (Although that won't cause problems if Interface is in fact a pure interface, lacking member variables.) If it helps, draw a diagram: every time a base class appears without the keyword virtual, it appears as a distinct object; all base classes that appear with the keyword virtual are condensed into one object.
[UPDATE: markh44's excellent answer shows that the above approach (of making Interface2 inherit virtually from Interface) will in fact allow Class2 to automatically inherit the implementation of method() from Base! Problem solved!]
This answer in a different forum seems to tackle the exact problem you mention.
In general, you should avoid the diamond inhertance pattern:
Interface
/ \
Base Interface2
\ /
Class2
This will cause you call kinds of grief down the road if you're not careful. Ambiguity will bite you.
In your specific instance there's no need for Interface2 to inherit from Interface. Interface2 doesn't need to specify "method" since it's abstract. Remove the inheritance between Interface and Interface2 to break the diamond. Then you're hierarchy looks like:
Interface Interface Interface2
| | |
Base Base |
| \ /
Class Class2
And your implementation looks like:
// concrete class - not specialised - OK
class Class: public Base
{
};
// concrete class - specialised
class Class2: public Base, public Interface2
{
virtual int method() {return 35;}
virtual void Inteface2Method { ... }
};

nonvirtual interface idiom for more than two levels of inheritance?

The non-virtual interface idiom describes how the virtual methods are nonpublic customisation points, and public methods are nonvirtual to allow the base class to control at all times how the customisation points are called.
This is an elegant idiom and I like to use it, but how does it work if the derived class is a base class in itself
It works, because the derived class can override a private virtual function of a base class, even if the base class function overrides its base class function.
This is perfectly legal:
class Parent
{
public:
int foo() {return bar();} // the non-virtual public interface
private
virtual int bar();
};
class Child : public Parent
{
private:
virtual int bar(); // overrides Parent::bar()
};
class Grandchild : public Child
{
private:
virtual int bar(); // overrides Child::bar();
};
The derived class can decide for itself:
You can just override the method completely by implementing the virtual function.
You can augment the method by calling the 'middle' classes function at some point in your derived class method.
If that's not what you want, you need to set it up explicitly in the 'middle' class. I wouldn't though. If you find yourself desiring this, it probably means you didn't give the base class enough customization points.