I have developed the following code in an attempt to implement non-virtual polymorphism:
#include <functional>
#include <iostream>
namespace{
using std::function;
class base {
protected:
using signiture =void(void);
using func_t = function<signiture>;
~base(){}
public:
func_t bar;//std::function object to a function of type "signature"
};
}
template <typename implementation>
class foo:public base {
public:
foo(implementation* instance){
bar = func_t(std::bind(&implementation::bar_implementation,instance));
//binds a function of name "bar_implementation" from class implementation to the std::function object
//binds to object "instance"
}
};
typedef base foo_base;
class testcase:public foo<testcase> {
public:
friend class foo;//allows implementations to be protected or private
testcase():foo(this){}//sends instance to the constructor of the base class in order to enable binding
protected:
void bar_implementation(void){
std::cout<<"Hello"<<std::endl;
}
};
class testcase2:public foo<testcase2> {
public:
friend class foo;//allows implementations to be protected or private
testcase2():foo(this){}
protected:
void bar_implementation(void){
std::cout<<"World!"<<std::endl;
}
};
int main(int argc, const char * argv[]) {
testcase t;
testcase2 t2;
foo_base* b = &t;
foo_base* b2 = &t2;
b->bar();
b2->bar();
return 0;
}
In reality this code is spread out over a few files...
I would like to know if anything in my code can be considered bad-practice,undefined behavior or otherwise undesirable in some manor?
A Live Example
Any thoughts on this pattern as a replacement for virtual inheritance and the design are appreciated.
Let me know if i can clarify anything.
EDIT:
I am asking this question as an attempt to determine if there are any reasons why a design like this would be a suitable way to implement non virtual polymorphism and if it is not, why is that?
Your code is an interesting approach. It's a nice proof of concept but it has a major flaw: it doesn't manage inheritance consistently !
The problem : class inheritance
Suppose I want to create a class testcase22 which inherits from testcase2, but has its own implementation of bar().
Alternative 1: if I define it naively by inheriting from testcase2, it will use the bar_implementation of testcase2:
class testcase22:public testcase2 {
public:
testcase22() {} // naive contructor
protected:
void bar_implementation(void){ // will not be used
std::cout<<"Great!"<<std::endl;
}
};
Alternative 2: If I try to use your constructor pattern, it won't work because of a compiling error. Because the type deduction will use foo<testcase2>, which is not a direct base class of testcase22 and can hence not be used in the mem-initializer list:
class testcase22:public testcase2 {
public:
friend class foo;//allows implementations to be protected or private
testcase22():foo(this){} // !!!!! causes compile error
protected:
void bar_implementation(void){
std::cout<<"Great!"<<std::endl;
}
};
Alternative 3: if I'd use foo explicitly, it would not work because foo os not either a valid base type initializer.
Alternative 4: if I'd try to use multiple inheritance, I'd be confronted to ambiguous base class
class testcase22:public testcase2, public foo<testcase22> {
public:
friend class foo;//allows implementations to be protected or private
testcase22():foo(this){}
protected:
void bar_implementation(void){
std::cout<<"Great!"<<std::endl;
}
};
This could be solved by defining foo inheriting virtually from base:
class foo:public virtual base { ... };
Then it would compile, but it still would use the bar_implementation of testcase2 instead of that from testcase22. By the way, even if it would have worked, the virtual base would prevent possibility of using multiple inheritance with your class family.
Conclusion
Your nice construct works, but only with a single level of simple inheritance.
This is a major constraint. Especially when considering that the benefit of polymorphism is to manage natural hierarchies making best use of the inheritance relationships.
Your pattern is also relatively complex to use in comparison with easy to use virtual functions. What will your code look like with several polymorphic functions, some of them even overloaded ?
The goals you intend to achieve with your pattern is not clear, but honestly, I wouldn't go for this approach for real life projects that have to be maintained over several years. But this is my own subjective opinion of course.
Related
This is a followup question of Static polymorphism with final or templates?. So it seems that the best solution for static-only polymorphism is to use CRTP. If you want runtime polymorphism, virtual functions are a good solution.
I find that not very elegant because the problems are actually very similar (and maybe you want to change the behavior at some point) but the code is actually very different. The code would in my opinion be more expressive if the solutions would be very similar and only differ at a single spot.
So I would like to know if there is a way to get static-only polymorphism with virtual functions. That might be something like an attribute or some construction to not allow pointers to the abstract base class. Is there such a feature and if not, am I missing something why such a feature should not exist? Are static and runtime polymorphism actually more different than such a feature would suggest?
EDIT: To make the question and the usecase a bit clearer, here is some example, that I would like to write:
[[abstract]] class Base {
public:
void bar() { /* do something using foo() */ }
private:
virtual void foo() = 0;
};
class Derived1 : public Base {
public:
Derived1();
private:
void foo() override { /* do something */};
};
class Derived2 : pulic Base {
public:
Derived2();
private:
void foo() override { /* do something with data */ }
int data;
};
where the non-existing attribute [[abstract]] means that there cannot exist an instance of the class Bass, even not by a pointer. This would clearly express static polymorphism and the compiler could optimize away virtual calls because they do not exist. Also a virtual destructor would not be necessary.
EDIT 2: The goal is to provide an abstract interface that can be slightly modified in further derived classes and has the same options for extending as an abstract class. So the main implementation is still in Base and the specific implementation of the virtual functions is in Derived.
You are more likely to get something the other way around, runtime polymorphism that looks like static polymorphism, or that looks like something completely different.
The metaclass proposals floated for post-reflection C++ (maybe c++26) look powerful enough to do stuff like:
Interface IBob {
void foo();
};
and
Implementation<Dispatch::Static> BobImpl:IBob {
void foo() {}
};
Implementation<Dispatch::Dynamic> BobImpl:IBob {
void foo() {}
};
to do roughly what you are asking. (Syntax is ridiculously far from final in the metaclass proposal(s); the expressive power is clearly there to do the above, however).
The dynamic case would set up vtables and the like (possibly not the standard C++ vtables however), and in the static case BobImpl would be unrelated to the type bob.
Of course, at that point, I expect there to be so many new ways to express polymorphism in C++ that "I want my CRTP to be written like a virtual function table C++ object" to be a bit like seeing atomic power technology coming over the horizon, and being excited that it could replace the coal burner on your steam-train.
So it seems that the best solution for static-only polymorphism is to use CRTP. If you want runtime polymorphism, virtual functions are a good solution.
In your linked question, you used CRTP to enforce an interface:
template <typename TData>
struct Base {
void foo() {
static_cast<TData*>(this)->doFoo();
}
This uses static polymorphism, but it's a very specific use. It does nothing at all but refuse to compile if your derived class doesn't have a suitable doFoo method. So I don't know how you reached your conclusion.
I find that not very elegant because the problems are actually very similar (and maybe you want to change the behavior at some point) but the code is actually very different. The code would in my opinion be more expressive if the solutions would be very similar and only differ at a single spot.
You lost me. Runtime polymorphism affects two things in C++:
declaration, since you must have a base class, the virtual keyword, and optionally override and final
use, when the call site uses virtual dispatch to find the correct method implementation
(although, as discussed, this may be optimized out when the static type is known).
Note also that although polymorphism is often discussed as being about relationships between objects, in C++ we're really only talking about method dispatch.
Static polymorphism only affects the call site. The fact that your other question used CRTP doesn't mean that is the only way of using static polymorphism.
If I write a template function
template <typename T>
void foo_it(T&& t) { t.foo(); }
then that uses static polymorphism. It will work for any T with a suitable foo method, whether it derived from Base<T> or not. It will even work for a T which overrides a virtual foo() from some other base class. This is duck typing.
Since it's unclear what you hope your [[abstract]] Base to achieve, I can only advise you to just write
class Derived {
public:
void foo();
};
and pass it around to function templates that expect some type implementing foo().
As a follow-up to your edit
So the main implementation is still in Base and the specific implementation of the virtual functions is in Derived
It's perfectly fine to do this using CRTP. That is an implementation detail which happens to use static polymorphism, not a virtual-like hierarchy.
For example
template <typename Derived>
struct Template {
Derived* virt() { return static_cast<Derived*>(this); }
int foo(int i) {
return i + virt->detail(i) + virt->extra();
}
};
struct A: public Template<A> {
int detail(int i) { return i*i; }
int extra() { return 17; }
};
struct B: public Template<B> {
int detail(int i) { return i % 23; }
int extra() { return -42; }
};
creates two independent types A and B, which provide the same interface int foo(int), and happen to share some code as an implementation detail.
It doesn't create a hierarchy. If you write a function template that takes some object of type T and calls the method int T::foo(int) on it, this will work. That is static polymorphism. It doesn't require a shared base class.
Assuming the question is how to enforce at compile time that derived classes
implement a base "abstract interface"
without polymorphism
keeping the implementation non-public, yet accessible to base class members
the following could be one way to do it.
#include <type_traits>
#include <iostream>
using std::cout;
using std::endl;
template<class Impl> class Base {
protected:
void foo() {
Bridge::virtual_foo(static_cast<Impl&>(*this));
}
struct Bridge : public Impl {
static void virtual_foo(Impl &that) {
static constexpr void (Impl::*fn)() = &Bridge::foo;
(that.*fn)();
}
static_assert(std::is_same<void (Impl::*)(), decltype(&Bridge::foo)>::value, "foo not implemented");
};
public:
void bar() {
cout << "begin Base::bar" << endl;
foo();
cout << "end Base::bar" << endl << endl;
}
};
class Good : public Base<Good> {
protected:
void foo() {
cout << "in Good::foo" << endl;
}
};
class Bad : public Base<Bad> {
};
int main() {
Good().bar();
// Bad().bar(); // static_assert: 'foo' not implemented
}
Output:
begin Base::bar
in Good::foo
end Base::bar
I have a number of free functions in namespace Util that operate on class A, in the spirit of proper encapsulation. Class A is an abstract interface, so the util function will receive specialized derived variants, e.g. B. Some of the free functions need to access private methods in A that I don't want to expose. This is mainly due to bad design in A which is hard to change because of its role in a larger hierarchy of components. A solution is to subclass A as Aimpl and write wrapper functions such:
class A { //Is abstract polymorphic interface
public:
virtual void SomeFunc() = 0;
protected:
void ProtectedFunc() {SomeOtherFunc();}
private:
void SomeOtherFunc();
};
class B : public A { //Overrides stuff in A and has added variables
public:
virtual void SomeFunc();
};
Defined in a separate file I have
namespace {
class Aimpl : public A {
public:
void WrapProtectedFunc() {ProtectedFunc();}
};
}
namespace Util {
void ProtectedFunc(A& instance) {
try {
Aimpl& aimpl = static_cast<Aimpl&>(instance);
aimpl.WrapProtectedFunc();
}
catch (std::bad_cast) {}
}
First I wanted to use dynamic_cast, but this obviously fails since I might get a B Reference, and B is not a Aimpl. But static_cast and reinterpret_cast work fine, tested on Linux gcc4.4.
I get the eerie feeling I am summoning dragons here. I've tried to search for this and I've come to understand this may in fact be undefined behaviour. But is it really? Can we not guarantee that this cast will work out, when Aimpl just adds a public function to the interface?
Suggestions to achieve this in a better way are much welcome too.
edit:
I've since found the right way to do this using friend functions, declare the Util function inside the A header file such:
namespace Util {
void ProtectedFunc(A& instance);
}
class A { //Is abstract polymorphic interface
public:
virtual void SomeFunc() = 0;
private:
void SomeOtherFunc();
friend void Util::ProtectedFunc(A& instance);
};
The definition of Util::ProtectedFunc goes in the cpp file, and the goal is achieved; all users can write Util::ProtectedFunc(instance) instead of instance->ProtectedFunc().
Won't work. First of all, WrapProtectedFunc is private so you can't call it anyway. The static_cast will compile, but you will get undefined behavior. This catch (std::bad_cast) {} is pointless, because static_cast never throws. Easy solution: Add WrapProtectedFunc as a public member to A, because if your free functions need access to internals of A, well, they need access to internals of A. And if A has any internals at all the term "abstract polymorphic interface" is not appropriate. BTW, Your class A as specified is neither abstract nor polymorphic.
Say you have a base class Dep for a tree of classes. There is a virtual method Dep* Dep::create() that I want to be implemented by every single leaf class. Is there any way to enforce this?
Note: The problem here is that there could be intermediate classes (say class B : public A : public Dep) implementing this method (A::create) by accident or because they think they are leaf classes, but are in fact subclassed themselves.
The question ends here.
Context
If you are curious why I need this; I have a class Master which has Dep objects of unknown concrete type. If Master is duplicated, I need to come up with a matching clone of the Dep instance. Next best thing to do is the virtual constructor idiom, which introduces precisely this problem.
Additionally, I cannot even catch this (other then by crashing horribly), because for obscure reasons, people that have more to say than me, have outlawed dynamic_cast in this project (perhaps this is a good decision; But anyways a completely different discussion).
C++ provides no way to keep a class from inheriting from your class, and there is no way to make a particular class in the inheritance hierarchy implement a method. The only rule is that somewhere in the inheritance hierarchy above a particular class (not necessarily in the leaf) all virtual functions must have an implementation for that class to be instantiatable.
For instance, A could inherit from Def and implement all it's [pure] virtual methods. Then if B inherits from A, it doesn't have to implement anything. There's no way to keep that from happening.
So the answer is no, there is no way to enforce this.
Using curiously recurring template fun, you can achieve something quite similar:
template<typename T>
class Cloneable : public T, public Dep
{
private:
Cloneable<T>() : T() { }
public:
static Cloneable<T>* Create() { return new Cloneable<T>(); }
Cloneable<T>* clone() { return new Cloneable<T>(*this); }
};
Instead of deriving from Dep and instantiating via new MyType, use Cloneable<MyType>::Create. Since Cloneable<MyType> is derived from MyType, you can use the instance the same way you would use any MyType, except that it is now guaranteed to have Dep::clone.
Additionally your Master should not accept an instance of type Dep, but enforce that it is a Cloneable<T>. (Replace your orignial function by a simple function template that enforces this.) This guarantees that any Dep inside the master has a correctly implemented clone function.
Since Cloneable<MyType> has no public constructor, it cannot be inherited, however your actual MyType can be further inherited and used just as before.
Did TPTB outlaw all RTTI, or only dynamic_cast<>()? If you can use RTTI, then you can enforce the existence of the method as a postcondition of calling it:
#include <typeinfo>
#include <cassert>
#include <iostream>
#include <stdexcept>
class Base {
protected:
virtual Base* do_create() = 0;
virtual ~Base() {}
public:
Base* create() {
Base *that = this->do_create();
if( typeid(*this) != typeid(*that) ) {
throw(std::logic_error(std::string() +
"Type: " +
typeid(*this).name() +
" != " +
typeid(*that).name()));
}
return that;
}
};
class Derive1 : public Base {
protected:
Base* do_create() { return new Derive1(*this); }
};
class Derive2 : public Derive1 {};
void f(Base*p) { std::cout << typeid(*p).name() << "\n"; }
int main() {
Derive1 d1;
Base *pD1 = d1.create(); // will succeed with correct semantics
Derive2 d2;
Base *pD2 = d2.create(); // will throw exception due to missing Derive2::do_create()
}
If you control the base class AbstractDep then you can enforce that concrete leaf classes must be created by using a class template WithCloning. This leaf can then be sealed so that it cannot be inherited. Or more precisely, instances cannot be created of a derived class.
class AbstractDep
{
template< class Type > friend class WithCloning;
private:
enum FooFoo {};
virtual FooFoo toBeImplementedByLeafClass() = 0;
public:
virtual AbstractDep* clone() const = 0;
};
template< class Type > class WithCloning;
class Sealed
{
template< class Type > friend class WithCloning;
private:
Sealed() {}
};
template< class Type >
class WithCloning
: public Type
, public virtual Sealed
{
private:
AbstractDep::FooFoo toBeImplementedByLeafClass()
{
return AbstractDep::FooFoo();
}
public:
virtual WithCloning* clone() const
{
return new WithCloning( *this );
}
};
typedef WithCloning<AbstractDep> Dep;
class AbstractDerivedDep
: public AbstractDep
{
// AbstractDep::FooFoo toBeImplementedByLeafClass(); // !Not compile.
public:
};
typedef WithCloning<AbstractDerivedDep> DDep;
struct Foo: Dep {}; // !Does not compile if instantiated.
int main()
{
Dep d;
//Foo f;
}
If the classes require more than default construction then that most be solved additionally.
One solution is then to forward an argument pack from the WithCloning constructor (there is an example C++98 implementation on my blog, and C++0x supports that directly).
Summing up, to be instantiable the class must be WithCloning.
Cheers & hth.,
when you say that they are unknown, i presume they still inherit from a common base class /interface right?
only thing i can think of you can use to force is on the virtual base class add
virtual Base* clone() {
assert( 1==0 ); //needs to be overriden
}
so you are forced to override, but this is only detected at run-time when trying to call clone on a instance of a class that is missing the override
even if you are not allowed to use dynamic_cast or RTTI, you can still enable it for debug purposes locally on your build, if that will help you find the typeid of offending classes
it sounds like you are familiar with the clone pattern, but i'll post it quietly in here, and we can forget about it:
http://www.cplusplus.com/forum/articles/18757/
i have an inheritance struct A : public B, i want to hide individual functions from B, is this possible?
i know the opposite is possible using using BMethod in the A declaration.
cheers
If you want to selectively hide functions from B it does not make much sense to use public inheritance in the first place.
Use private inheritance & selectively bring methods from B into the scope of A:
struct B{
void method1(){};
void method2(){};
};
struct A : private B{
using B::method1;
};
A a;
a.method1();
a.method2(); //error method2 is not accesible
There is an issue here: this would be a direct violation of the Liskov Substitution Principle, namely A would not act as a B any longer.
If you wish to reuse B implementation, the solution is simply to do so:
class A
{
public:
void foo() { return b.foo(); }
void bar() { return b.bar(); }
// ...
private:
B b;
};
Don't abuse inheritance, use composition instead
The using keyword can be used to change visibility
struct A
{
void method1();
};
struct B: public A
{
void method2();
private:
using A::method1;
};
Aside from the ways described in the previous answers—composition, private inheritance, and non-private inheritance but with the inherited method declared private—another way is to explicitly delete the inherited method:
#include <iostream>
struct A {
void foo() { std::cout << "foo\n"; }
};
struct B : A {
void foo() = delete;
};
int main() {
B b;
b.foo(); // COMPILER ERROR
}
Although the b.foo() call produces a compiler error, client code can still call the base class’s version by qualifying with the base class identifier A:
b.A::foo(); // compiles, outputs 'foo' to console
This explicit deletion way works when foo is not a virtual non-deleted method in A. By C++11 Standard §10.3/16, this explicit deletion is ill-formed when the deleted method in the derived class overrides a virtual non-deleted method of the base class. For more info on this restriction, see the answers to the SO question C++11 Delete Overriden Method.
You can't "hide it" per se, but you can make it a compile time error to call it. Example:
struct A
{
void AMethod() {}
};
class B : public A
{
void AMethod() {} //Hides A::AMethod
};
int main()
{
B myB;
myB.AMethod(); //Error: AMethod is private
static_cast<A*>(&myB)->AMethod(); //Ok
return 0;
}
Examples on codepad with the error, and without.
That all said, despite this being possible, you really shouldn't do it. You'll confuse the hell out of clients.
EDIT: Note that you can also do this with virtual functions (And with the error).
To those that are suggesting composition... this might not be the best possible way of going about things. My understanding is that the Liskov Substitution Principle only states that there's the possibility of the functions from the base class being used on the child, not that they necessarily should be. For example, for a particular base class you may have multiple functions that essentially perform the same operation, but for different specific cases. In the derived class you may want to abstract these public functions away in favor of simplifying the user's interface. This is where private inheritance can be used. Private inheritance might also be a necessity, if we have protected functions in the base class that we don't want the user of the base class to call, yet would be invaluable to the derived class.
In short, if you HAVE to, use private inheritance, but composition is preferred in most cases.
There is yet another approach.
class A{
void f1();
void f2();
void f3();
}
class BInterface{
void f2();
void f3();
}
class B : public A, BInterface
{
}
BInterface b = new B();
b->f1(); //doesn't work since f1 is not declared in BInterface
b->f2(); //should work
b->f3(); //should work
delete(b);
Use BInterface as a filter for inherited classes to exclude undesirable methods. Liskov Substitution principle isn't violated in this case since an object of BInterface class is not an object of A class even though that an object of B class is an object of BInterface class.
If the methods are private in B, then they will remain hidden to a even if you use public inheritance.
Can't alter the visibility of the original method.
You could create a method in struct A with the same name and have that method be private, but that doesn't prevent the method from being called when an instance of struct A is being referenced by a variable of type B.
Why don't you make it Virtual in the base class and override it in its Children? (more help)
Recently one of my friend asked me how to prevent class inheritance in C++. He wanted the compilation to fail.
I was thinking about it and found 3 answers. Not sure which is the best one.
1) Private Constructor(s)
class CBase
{
public:
static CBase* CreateInstance()
{
CBase* b1 = new CBase();
return b1;
}
private:
CBase() { }
CBase(CBase3) { }
CBase& operator=(CBase&) { }
};
2) Using CSealed base class, private ctor & virtual inheritance
class CSealed
{
private:
CSealed() {
}
friend class CBase;
};
class CBase : virtual CSealed
{
public:
CBase() {
}
};
3) Using a CSealed base class, protected ctor & virtual inheritance
class CSealed
{
protected:
CSealed() {
}
};
class CBase : virtual CSealed
{
public:
CBase() {
}
};
All the above methods make sure that CBase class cannot be inherited further.
My Question is:
Which is the best method ? Any other methods available ?
Method 2 & 3 will not work unless the CSealed class is inherited virutally. Why is that ? Does it have anything to do with vdisp ptr ??
PS:
The above program was compiled in MS C++ compiler (Visual Studio).
reference : http://www.codeguru.com/forum/archive/index.php/t-321146.html
As of C++11, you can add the final keyword to your class, eg
class CBase final
{
...
The main reason I can see for wanting to do this (and the reason I came looking for this question) is to mark a class as non subclassable so you can safely use a non-virtual destructor and avoid a vtable altogether.
You can't prevent inheritance (before C++11's final keyword) - you can only prevent instantiation of inherited classes. In other words, there is no way of preventing:
class A { ... };
class B : public A { ... };
The best you can do is prevent objects of type B from being instantiated. That being the case, I suggest you take kts's advice and document the fact that A (or whatever) is not intended to be used for inheritance, give it a non-virtual destructor, and no other virtual functions, and leave it at that.
You are going through contortions to prevent further subclassing. Why? Document the fact that the class isn't extensible and make the dtor non-virtual. In the spirit of c, if someone really wants to ignore the way you intended this to be used why stop them? (I never saw the point of final classes/methods in java either).
//Note: this class is not designed to be extended. (Hence the non-virtual dtor)
struct DontExtened
{
DontExtened();
/*NOT VIRTUAL*/
~DontExtened();
...
};
1) is a matter of taste. If I see it correctly, your more fancy 2nd and 3rd solutions move the error in certain circumstances from link time to compile time, which in general should be better.
2) Virtual inheritance is needed to force the responsibility to initialize the (virtual) base class to the most derived class from where the base class ctor is no longer reachable.
To answer your question, you can't inherit from CBase because in virtual inheritance a derived class would need to have direct access to the class from which it was inherited virtually. In this case, a class that would derive from CBase would need to have direct access to CSealed which it can't since the constructor is private.
Though I don't see the usefulness of it all (ie: stopping inheritance) you can generalize using templates (I don't think it compiles on all compilers but it does with MSVC)
template<class T>
class CSealed
{
friend T; // Don't do friend class T because it won't compile
CSealed() {}
};
class CBase : private virtual CSealed<CBase>
{
};
If you can, I'd go for the first option (private constructor). The reason is that pretty much any experienced C++ programmer will see that at a glance and be able to recognize that you are trying to prevent subclassing.
There might be other more tricky methods to prevent subclassing, but in this case the simpler the better.
From C++11 onward, there is a clean solution that I am surprise not to see here. We can make the class final preventing any further inheritance.
class Foo final {};
class Bar: public Foo {}; // Fails to compile as Foo is marked as final
class myclass;
class my_lock {
friend class myclass;
private:
my_lock() {}
my_lock(const my_lock&) {}
};
class myclass : public virtual my_lock {
// ...
public:
myclass();
myclass(char*);
// ...
};
myclass m;
class Der : public myclass { };
Der dd; // error Der::dd() cannot access
// my_lock::my_lock(): private member
I found it here to give credit. I am posting here just other people can easily access
http://www.devx.com/tips/Tip/38482
To elaborate on Francis' answer: if class Bottom derives from class Middle, which virtually inherits from class Top, it is that most derived class (Bottom) that is responsible for constructing the virtually inherited base class (Top). Otherwise, in the multiple-inheritance/diamond-of-death scenario (where virtual inheritance is classically used), the compiler wouldn't know which of the two "middle" classes should construct the single base class. The Middle's constructor's call to the Top's constructor is therefore ignored when Middle is being constructed from Bottom:
class Top {
public:
Top() {}
}
class Middle: virtual public Top {
public:
Middle(): Top() {} // Top() is ignored if Middle constructed through Bottom()
}
class Bottom: public Middle {
public:
Bottom(): Middle(), Top() {}
}
So, in the the approach 2) or 3) in your question, Bottom() can't call Top() because it's inherited privately (by default, like in your code, but it's worth making it explicit) in Middle and thus is not visible in Bottom. (source)