accessing private members using base pointer

Hi,
I have written a program just to get some understanding of how virtual pointers works w.r.t base and derived class when inherited.

below is my program, the question is when derived class overrides the base function , but function is in private scope of derived, how base pointer can access the private derived class member function?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <iostream>

using namespace std;

class base{
    public:
    void virtual common_fun() {
        cout<<"common_fun base "<<endl;
    }
};

class derived: public base {
   // public:
    void common_fun() {
        cout<<"common_fun derived "<<endl;
    }

    void derived_fun() {
        cout<<"derived_fun"<<endl;
    }
    
};

int main() {
    base *bptr = new base;
    bptr->common_fun(); // outputs common_fun base ==> OK
    derived *dptr = new derived;
    bptr = dptr;
    bptr->common_fun(); // outputs common_fun derived( but how ? common_fun is in private scope of derived )
    //derived dobj;
    //dobj.common_fun(); // error as expected , since private members cannot be accessed by obj directly.
    return 0;
}
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>

class base{
    public:
    void virtual common_fun() {
        std::cout << "common_fun base \n";
    }
};

class derived: public base {
   // public:
    void common_fun() {
        std::cout << "common_fun derived \n";
    }
};

int main() {
    base x;
    derived y;
    x.common_fun();
    // y.common_fun(); // error: 'virtual void derived::common_fun()' is private
    // error: within this context
    base* ptr = &y;
    ptr->common_fun();
}

The main() uses the interface of base: base::common_fun(). For all it knows, common_fun() is accessible. For example, the *ptr does not have "derived_fun()".

What the user does not need to know is that the derived supplies a modified version of common_fun(). The derived IS-A base and base has public and virtual common_fun().


Herb Sutter did recommend:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class base{
public:
    void common_fun() { common_impl(); }
private:
    virtual void common_impl() {
        std::cout << "common_fun base \n";
    }
};

class derived: public base {
    void common_impl() {
        std::cout << "common_fun derived \n";
    }
};

In this version it is more explicit that common_fun() is part of interface and the derived classes can replace the private implementation.
but function is in private scope of derived, how base pointer can access the private derived class member function?
The base class does not know anything about the derived class.

When the base class is instantiated/constructed it places all virtual function into a virtual table. The derived class does the same. I.e. it replaces the functions with the same signature of the base class. Scope doesn't apply here.

Okay, please correct me if my understanding is wrong.

All derived member functions which match the prototype of base virtual functions will be overridden no matter what their scope is (private/public/protected), if invoked by base pointer which has the address of derived object.
Last edited on
Almost. The 'virtual' keyword is what makes the magic happen.


Edit: Yeah, I think you got it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#include <iostream>

class Base
{
public:
    void hidden_function()
    {
        std::cout << "Base class hidden function" << std::endl;
    }

    virtual void overridden_function()
    {
        std::cout << "Base class overridden function" << std::endl;
    }
};

class Derived : public Base
{
public:
    void hidden_function()
    {
        std::cout << "Derived class hidden function" << std::endl;
    }

    void overridden_function()
    {
        std::cout << "Derived class overridden function" << std::endl;
    }
};

int main()
{
    Base b;
    Derived d;

    // As expected
    std::cout << "Normal behavior" << std::endl;
    b.hidden_function();
    b.overridden_function();
    d.hidden_function();
    d.overridden_function();


    // Base class pointer to derived object
    Base* b_ptr = &d;

    std::cout << "\nBase* pointing to Derived object" << std::endl;
    // hidden_function is not virtual, so a Base* only understands
    // Base::hidden_function.  Call the Base:: version.
    b_ptr->hidden_function();

    // overridden_function is virtual, so Base* looks up the latest
    // local definition of overridden_function in the v-table and
    // calls it.  Thus Derived::overridden_function is called.
    b_ptr->overridden_function();



    // Bonus material.
    // Using an object of the Derived class, specifically call the
    // Base:: implementations of the functions.
    std::cout << "\nBONUS! Base:: behavior on Derived object" << std::endl;
    d.Base::hidden_function();
    d.Base::overridden_function();

    return 0;
}
Last edited on
> All derived member functions which match the prototype of base virtual
> functions will be overridden no matter what their scope is
> (private/public/protected), if invoked by base pointer which has the address
> of derived object.
dunno, perhaps it's implementation defined or plain old undefined behaviour
make it simple, don't try to shoot your foot.

also, I think that you're violating liskov there (Preconditions cannot be strengthened in a subtype.)
Last edited on
All derived member functions which match the prototype of base virtual functions will be overridden no matter what their scope is (private/public/protected), if invoked by base pointer which has the address of derived object.
The base class functions will be overriden. The derived functions will override the base class functions.

Scope does not affect the virtual table. When you are trying to access a function no matter if it is virtual or not the scope will have an effect.

In a further derived class you can change the scope again. The virtual function will be overriden even if it was previously private. So again: Scope does not affect the 'virtuality' of functions.

[EDIT]
Actually 'scope' is the wrong term here. See:

https://en.cppreference.com/w/cpp/language/scope

The correct term for public/protected/private is access specifiers. See:

https://en.cppreference.com/w/cpp/language/access
Last edited on
If in any job interview these kind questions are asked then what should be the correct response.
when derived class overrides the base function , but function is in private scope of derived, how base pointer can access the private derived class member function?


IMHO
as long as it's virtual it will be able to access directly (override suffix in derived to make sure it virtual)
Last edited on
Topic archived. No new replies allowed.