2

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;
}
Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
Ravi
  • 37
  • 1
  • 3

3 Answers3

2

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.

Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
  • Very complete answer. – chema989 Jun 25 '16 at 06:40
  • Thanks - I added one protected function foo() in MakeFinal class and tried to access that through *finalUserHeap_ but compiler says foo() is inaccessible to finalUserHeap_. Does this mean what you explained is valid only for constructors? – Ravi Jun 25 '16 at 07:00
  • @Ravi: It's accessible in class `FinalUser`, just as the constructor, but only for calls on object of known type `FinalUser` or derived. I would guess your test code called it on an object of known type `Final` or `MakeFinal`. This restriction on `protected` is a light-weight defense against the case of inadvertently deriving form the base class and accessing a sibling class' protected parts. – Cheers and hth. - Alf Jun 25 '16 at 07:37
  • Another possibility is that you tried to call the `protected` method directly via the pointer `finalUserHeap` in `main`. If so then the compiler would protest because the method is not accessible to `main`. – Cheers and hth. - Alf Jun 25 '16 at 07:40
  • Yes, you are right... Stupid of me to call foo from main. Now it's very clear. Thanks a lot, Cheers! – Ravi Jun 25 '16 at 07:48
  • @Cheersandhth.-Alf But it is accessible through the (pointer to) FinalUser object in main. The call to the MakeFinal() base ctor is **more direct** than the call to any other MakeFinal member function in that it by-passes any additional access restrictions imposed via the virtual inheritence through Final (e.g. if that was private, the MakeFinal ctor would get called fine but `finalUserHeap->foo()` would be access restricted. – Don Slowik Oct 22 '21 at 21:14
1

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.

Community
  • 1
  • 1
chema989
  • 3,962
  • 2
  • 20
  • 33
0

Derived classes have access to protected members of their base classes. That's the difference between protected and private.

Bo Persson
  • 90,663
  • 31
  • 146
  • 203