C++: overriding public\private inheritance

11,322

Solution 1

If B inherits from A using public, can B override one of the functions and force it to be private? NO

Eventhough the my_func1() is declared under priavte access specifier it can be still called through a pointer to class A, actually pointing to a object of class B

The call to my_func1() is evaluated at run time depending on the type of objected pointed by the pointer. At compile time the compile sees the my_func1() call as call to A::my_func1() and since A::my_func1() is public the compiler doesn't report only error. It is only at runtime that actual function call B::my_func1() is evaluated.

Ofcourse, You cannot directly call my_func1() through object of class B though because B::my_func1() is declared under Private Access specifier and You cannot access privately declared members from outside the class.

How about the other way around? if the inheritance type is private - can B force a specific function to be public?
NO

If you are calling my_func1() through a pointer of the Base class A, At compile time it is just evaluated as call to A::my_func1() which is Invalid since A::my_func1() is declared private inclass A`

What if A is pure abstract? does it make a difference?
NO
It makes no difference if the base class is Abstract or just polymorphic. Same rules will be applicable.

Would protected make any difference in any combination?
NO
As explained in first 2 Q's if you are calling a virtual function thorough pointer to Base class then at compile time the compiler only checks the access of that member function in Base class because compiler sees it as call to Base class member function. The actual call to the function is evaluated at run time and the feature is called Runtime Polymorphism or Dynamic polymorphism which is independent of the Access specifiers, which as a compile time construct.

So in conclusion,

overriding members of Base Class does not affect access

Solution 2

Difference

What if A is pure abstract? does it make a difference?

The only difference it makes is the following, i.e how they can (or cannot) be used:

A *pa = new B();
pa->my_func2(10); //calls B::my_func2() even though its private!

B *pb = new B();
pb->my_func2(10); //compilation error - trying to access private function

Explanation

Access-specifiers are compile-time construct, and so, the compiler detects any violation of access-rules at compile-time (obviously) based on the static type of the object (or pointer). Such violation cannot be detected at runtime.

So pa->my_func2() works, because the compiler sees that the static type of pa is A* which has a public function my_func2() defined, so the expression pa->my_func2() passes the compiler's test. Hence it works.

But pb->my_func2() doesn't work, since the static type of pb is B* which has a private function my_func2(), hence the code wouldn't even compile!

Solution 3

==> If B inherits from A using public, can B override one of the functions and force it to be private?

NO. Pointer/reference to A will always see my_func2 as public. You can still call this method using A* or A&. (what you ask is possible in Java).

==> if the inheritance type is private - can B force a specific function to be public?

At 1st place if the inheritance type is private/protected then you can NOT assign object of Derived class to Base class pointer/reference. e.g. you can not do following!!

A* p = new B; // error

==> What if A is pure abstract? does it make a difference?

NO difference (except you have to define methods in B)

==> Would protected make any difference in any combination?

NO difference (with respect to Base class)

Solution 4

What you override does not affect access. So you can create public override of privately inherited function exactly the same way you create private override of publicly inherited function.

The public override of the privately inherited function obviously has to call the real function and it should be inline, so the compiler will optimize it away.

Solution 5

I was going through posts made by others and found explanation related to errors encountered when inheritance being private/protected in Derived class somewhat confusing/incomplete.

Consider below code snippet,

class A
{
public:
    virtual double my_func1(int i);
    virtual double my_func2(int i);
}

class B : private A // Notice private inheritance
{
public:
    virtual double my_func1(int i);
private:
    virtual double my_func2(int i);
}

A* ptr = new B; // this is not legal because B has a private base
ptr->my_func1(); // my_func1() is not accessible
ptr->my_func2(); // my_func2() is also not accessible not because it is private but due 
                 // base class A being inherited privately 

So when we inherit class B from class A using private/protected specifiers then it means that nobody in outside world knows that class B has inherited from class A hence it's illegal to assign pointer/reference of type class B to pointer/reference of type class A. Hence, access of private/protected overridden virtual function in derived classes is only valid when inheritance in public.

Share:
11,322
Jonathan Livni
Author by

Jonathan Livni

python, django, C++ and other vegetables...

Updated on June 05, 2022

Comments

  • Jonathan Livni
    Jonathan Livni about 2 years

    If B inherits from A using public, can B override one of the functions and force it to be private?

    class A
    {
    public:
        virtual double my_func1(int i);
        virtual double my_func2(int i);
    }
    
    class B : public A // Notice the public inheritance
    {
    public:
        virtual double my_func1(int i);
    private:
        virtual double my_func2(int i);
    }
    

    How about the other way around? if the inheritance type is private - can B force a specific function to be public?

    What if A is pure abstract? does it make a difference?

    Would protected make any difference in any combination?

  • Jonathan Livni
    Jonathan Livni about 13 years
    Although I chose this as the answer, I recommend reading the other answers for additional subtleties
  • mr5
    mr5 over 10 years
    Please tell us if this is a bad or a not bad practice to implement such structure?
  • Sukhanov Niсkolay
    Sukhanov Niсkolay almost 10 years
    So private inheritance is dangerous? Because you think that everything cannot be accessed, but you can access private virtual methods through base class.
  • StahlRat
    StahlRat over 9 years
    @mr5 Even so it works it is a flow and source of potential problems. Btw, Nawaz thx for very clear explanation.
  • Johannes Matokic
    Johannes Matokic over 8 years
    @Sukhanov: No, it is not dangerous, as the the deriving class is in full control of whether it makes access to its private base-class possible. So "A *a = new B();" is not allowed when A is a private base class of B
  • Johannes Matokic
    Johannes Matokic over 8 years
    The answer is not fully correct. If A is base class of B it is true that a private method of A could no way be accessed through a pointer of type A* but it is still possible to make it public in B using the using A::my_func; syntax. This is still true if A is a private base class of B. => Overriding members of Base Class does affect access, but not in the Base Class itself