Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can I access a derived private member function via a base class pointer to a derived object?

#include<iostream>  using namespace std; class base { public:     virtual void add() {         cout << "hi";     } };  class derived : public base { private:     void add() {         cout << "bye";     } };  int main() {     base *ptr;     ptr = new derived;     ptr->add();     return 0; } 

Output is bye

I dont have a problem with how this is implemented. I understand you use vtables and the vtable of derived contains the address of the new add() function. But add() is private shouldn't compiler generate an error when I try to access it outside the class? Somehow it doesn't seem right.

like image 359
Bruce Avatar asked Aug 31 '10 16:08

Bruce


People also ask

Can derived class access private members of base class?

Private members of the base class cannot be used by the derived class unless friend declarations within the base class explicitly grant access to them.

Can a base class pointer access derived class function?

Explanation: A base class pointer can point to a derived class object, but we can only access base class member or virtual functions using the base class pointer because object slicing happens when a derived class object is assigned to a base class object.

Why Cannot any derived class access its private data members and private member function of its base class?

To protect you from future changes to the base class. Derived classes do not get access to private members of a base class. This effectively “seals off” the derived class from any changes made to the private members of the base class.

How can you access a private member of a base class?

Private: The class members declared as private can be accessed only by the member functions inside the class. They are not allowed to be accessed directly by any object or function outside the class. Only the member functions or the friend functions are allowed to access the private data members of the class.

Why can't a derived pointer reference a base object?

similarly a derived object is a base class object (as it's a sub class), so it can be pointed to by a base class pointer. However, a base class object is not a derived class object so it can't be assigned to a derived class pointer.

Can base class access derived members?

No, you cannot access any derived class members using base class pointer even pointing to a derived class instance.


2 Answers

add() is only private in derived, but the static type you have is base* - thus the access restrictions of base apply.
In general you can't even know at compile time what the dynamic type of a pointer to base will be, it could e.g. change based on user input.

This is per C++03 §11.6:

The access rules (clause 11) for a virtual function are determined by its declaration and are not affected by the rules for a function that later overrides it.
[...] Access is checked at the call point using the type of the expression used to denote the object for which the member function is called [...]. The access of the member function in the class in which it was defined [...] is in general not known.

like image 173
Georg Fritzsche Avatar answered Oct 19 '22 03:10

Georg Fritzsche


Access modifiers, such as public, private and protected are only enforced during compilation. When you call the function through a pointer to the base class, the compiler doesn't know that the pointer points to an instance of the derived class. According to the rules the compiler can infer from this expression, this call is valid.

It is usually a semantic error to reduce the visibility of a member in a derived class. Modern programming languages such as Java and C# refuse to compile such code, because a member that is visible in the base class is always accessible in the derived class through a base pointer.

like image 25
Hosam Aly Avatar answered Oct 19 '22 02:10

Hosam Aly