6

I was trying to understand the implementation code of "final" in cpp:

following is the code:

/* A program with compilation error to demonstrate that Final class cannot
   be inherited */

class Final;  // The class to be made final

class MakeFinal // used to make the Final class final
{
private:
    MakeFinal() { cout << "MakFinal constructor" << endl; }
friend class Final;
};

class Final : virtual MakeFinal
{
public:
    Final() { cout << "Final constructor" << endl; }
};

class Derived : public Final // Compiler error
{
public:
    Derived() { cout << "Derived constructor" << endl; }
};

int main(int argc, char *argv[])
{
    Derived d;
    return 0;
}

Output: Compiler Error

In constructor 'Derived::Derived()':
error: 'MakeFinal::MakeFinal()' is private

In this I could not understand the logic of virtually inheriting the MakeFinal class. We could simply have inherited it(makeFinal class) as public and even in that case we would have not been able to inherit it further(because the constructor of Makefile is private and only Final class being its friend could have the access of it).

Any pointer??

bash.d
  • 13,029
  • 3
  • 29
  • 42
pjain
  • 1,149
  • 2
  • 14
  • 28
  • Did you actually try it with non-virtual inheritance? –  Jun 19 '13 at 06:50
  • 1
    A `private constructor` has nothing to do with not being able to inherit or not. I seriously don't get what you are trying to do. – bash.d Jun 19 '13 at 06:50
  • @bash.d Sure it does. You cannot derive from a class if that requires a call to an inaccessible constructor (because the constructor is private). –  Jun 19 '13 at 06:53
  • @bash.d A `private` ctor has quite a lot to do with not being able to inherit. For example, if you only give your class private constructors, you will never be able to instantiate a derived class. – Angew is no longer proud of SO Jun 19 '13 at 06:53
  • possible duplicate of [c++ virtual inheritance](http://stackoverflow.com/questions/2126522/c-virtual-inheritance) – BЈовић Jun 19 '13 at 06:59
  • read about: http://stackoverflow.com/questions/8824587/purpose-of-the-final-keyword – EGOrecords Jun 19 '13 at 07:04

1 Answers1

11

It wouldn't work. Non-virtual base classes are always initialised by the class which is immediately derived from them. That is, if the scenario were as follows:

class Final : public MakeFinal
{
public:
  Final() {}
};

class Derived : public Final
{};

then the ctor of Derived only initialises Final, which is fine (Final has a public ctor). Final's ctor then initialises MakeFinal, which is also possible, since Final is a friend.

However, for virtual base classes, the rule is different. All virtual base classes are initialised by the ctor of the most-derived object. That is, when creating an instance of Final, it's Final's ctor which initialises MakeFinal. However, when trying to create an instance of Derived, it must be Derived's ctor which initialises MakeFinal. And that is impossible, due to MakeFinal's private ctor.

Also note that C++11 introduced the keyword final for classes (and virtual functions).

Angew is no longer proud of SO
  • 167,307
  • 17
  • 350
  • 455
  • Thanks @Angew.Can you please direct me to some resource/link where I can find more details about how virtual inheritance is actually implemented in gcc? My another intention is to get the insight how the diamond problem is actually solved by compiler. – pjain Jun 19 '13 at 08:06
  • @pjain Sorry, I can't help you here. I know little about compiler implementations. – Angew is no longer proud of SO Jun 19 '13 at 08:13