Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"final" class implementation in c++

Tags:

c++

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??

like image 258
pjain Avatar asked Jun 19 '13 06:06

pjain


1 Answers

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).

like image 174
Angew is no longer proud of SO Avatar answered Sep 24 '22 06:09

Angew is no longer proud of SO