0

While Simulating final Class in C++, why is "virtual" keyword used? C++ program without any compilation error to demonstrate that instances of the Final class can be created

#include <iostream>
using namespace std;

class Final;

class MakeFinal {
private:
    MakeFinal() { cout << "MakeFinal constructor" << endl; }
    friend class Final;
};

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

int main(int argc, char* argv[])
{
    Final f;
    return 0;
}
  • 2
    Related to [what-is-virtual-inheritance-in-c++](https://stackoverflow.com/questions/5910301/what-is-virtual-inheritance-in-c) – Jarod42 Sep 21 '22 at 10:47
  • 3
    there is no need to simulate a final class. C++ has final classes https://en.cppreference.com/w/cpp/language/final – 463035818_is_not_an_ai Sep 21 '22 at 11:07
  • In the particular example you have given there is no point to using `virtual` inheritance. However, in a scenario with multiple inheritance (e.g. your `Final` and a `Final2` that both inherit from `MakeFinal`, and then another class that inherits from both `Final` and `Final2`) the difference can be significant. – Peter Sep 21 '22 at 11:27
  • [Dupe1](https://stackoverflow.com/questions/419943/virtual-inheritance), [Dupe2](https://stackoverflow.com/questions/21558/in-c-what-is-a-virtual-base-class) and [Dupe3](https://stackoverflow.com/questions/5910301/what-is-virtual-inheritance-in-c). – Jason Sep 21 '22 at 11:28
  • I thoroughly checked the duplicates, and I did not find a question that is about the most derived class needing to call the virtual base constructor, nor mentioning the use to make a class final. Hence after careful consideration, I came to the conlusion that the question here is not fully answered by the duplicates and voted to reopen. – 463035818_is_not_an_ai Sep 21 '22 at 11:32
  • @Peter I thought the same initially. The point of `virtual` in the example is to prevent other classes inheriting further from `Final`. – 463035818_is_not_an_ai Sep 21 '22 at 11:43
  • @463035818_is_not_a_number Thanks for pointing that out. – Peter Sep 21 '22 at 12:09

1 Answers1

3

With virtual inheritance the most derived class must call the constructor of the virtual base class (in contrast to non-virtual inheritance where each class constructs its direct bases). Because MakeFinals constructor is private and only Final is a friend, no other classes can access MakeFinals constructor. Consequently you cannot derive from Final. More accurately you can derive:

struct OK : Final {};

but you cannot create instances, because constructing a OK would require to call the private MakeFinal constructor:

OK not_ok; // error: use of deleted function 'OK::OK()'

Without virtual inheritance this wouldn't work as intended, because then OKs constructor would call Finals constructor which in turn calls MakeFinals constructor. All would be fine. Only with virtual inheritance the most derived class must call the virtual base class constructor.


Note that since C++11, this "simulation" is not required. There is final to explicitly make a class final.


[...] without any compilation error to demonstrate that instances of the Final class can be created

Not sure if this is a misunderstanding. Of course you can create instances of a final class. When a class is final you just cannot inherit from it any further. (As explained above in your "simulation" one can inherit from Final, its just pretty useless because no instances can be constructed of a class inheriting from Final).

Alan Birtles
  • 32,622
  • 4
  • 31
  • 60
463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185