In C++ how can we call private function through an object without using friend function?
Asked Answered
M

2

5

I came across this code written in C++ :

#include<iostream>
using namespace std;

class Base {
public:
    virtual int fun(int i) { cout << "Base::fun(int i) called"; }
};

class Derived: public Base {
private:
    int fun(int x)   { cout << "Derived::fun(int x) called"; }
};

int main()
{
    Base *ptr = new Derived;
    ptr->fun(10);
    return 0;
}

Output:

 Derived::fun(int x) called 

While in the following case :

#include<iostream>
using namespace std;

class Base {
public:
    virtual int fun(int i) { }
};

class Derived: public Base {
private:
    int fun(int x)   {  }
};
int main()
{
    Derived d;
    d.fun(1);
    return 0;
} 

Output :

Compiler Error.

Can anyone explain why is this happening ? In the first case , a private function is being called through an object.

Menken answered 22/9, 2012 at 19:41 Comment(15)
"Without using friend" - learn C++ yourself and you won't need your friend to code it for you. (JK)Andie
@H2CO3 OP meant friend keyword :)Swaddle
d.fun(1) isn't a virtual function call, but ptr->fun(10) is.Weese
@Zyx2000 Why is that so ? Derived also has fun() of Base isn't it?Menken
You have virtual int but an integer is not being returned in those functions..Glidden
@sTEAK. Google for late binding.Plourde
@sTEAK. calls through pointers will be virtual, calls directly on the object won't. The exact type of d will always be known at the point of the call.Weese
@BartekBanachewicz I know , late binding / run time binding / dynamic binding. What am asking is , when we use . (dot) operator then late binding doesn't take place ? Does it take place in case of pointers only ?Menken
@Zyx2000 Thanks that clarifies it.Menken
@Swaddle If I didn't know C++, that comment of mine wouldn't be funny...Andie
This will make it compile: ((Base &)d).fun(1);Foal
@H2CO2 at least I learnt what (JK) means :) I realized too late that it was funny ... I should go sleep, it's too late...Swaddle
@Zyx2000 You shall make your comment an answer and I will accept that.Menken
@sTEAK : All this has nothing to do with use of -> or . operators. It only has to do with the type you use to call the method: If you call the method through Base, it will compile as the method Base::fun is public. If you call the method through Derived, it will fail as Derived::fun is private. . . Now, fun is virtual, meaning that calling it means, by default, dynamic binding... Unless the compiler can guarantee the exact type of the object at compile time. In that case, the call will be optimized, to be statically resolved to the right method.Sacring
possible duplicate of Why can I access a derived private member function via a base class pointer to a derived object?Goldengoldenberg
E
3

Polymorphism is happening in the first case. It causes dynamic or late binding. And as mentioned in the second answer, it can become quite dangerous at times.

You cannot access the private interface of a class from the outside of class definition directly. If you want to access the private function in the second instance without using a friend function, as title of your question implies, make another public function in your class. Use that function to call this private function. Like this.

 int call_fun (int i) ;

Call the fun() from inside it.

int call_fun (int i)
{
  return fun (i) ;  //something of this sort, not too good
}

The functions like this which are used just to call another function are known as wrapper functions.

Making friends is also not advisable always. It is against the principle of information hiding.

Enterectomy answered 22/9, 2012 at 19:47 Comment(2)
Though I agree with <quote>Making friends is also not advisable always.</quote> I definitely think <quote>It is against the principle of information hiding</quote> is wrong. Friendship does not break encapsulation in increases it. The alternative to friendship is to expose the data to more systems (which does break encapsulation). Friendship increases encapsulation at the cost of tightly coupling the friend and thus making it part of the interface. programmers.stackexchange.com/a/99595/12917Ablaze
I agree with that. But it generally depends upon the approach, the situation and the problem in hand. As in this one, friendship can easily be avoided.Enterectomy
P
4

Because in the first case you're using declaration from Base, which is public, and the call is being late-bound to the Derived implementation. Note that changing the access specifier in inheritance is dangerous and can nearly always be avoided.

Plourde answered 22/9, 2012 at 19:46 Comment(0)
E
3

Polymorphism is happening in the first case. It causes dynamic or late binding. And as mentioned in the second answer, it can become quite dangerous at times.

You cannot access the private interface of a class from the outside of class definition directly. If you want to access the private function in the second instance without using a friend function, as title of your question implies, make another public function in your class. Use that function to call this private function. Like this.

 int call_fun (int i) ;

Call the fun() from inside it.

int call_fun (int i)
{
  return fun (i) ;  //something of this sort, not too good
}

The functions like this which are used just to call another function are known as wrapper functions.

Making friends is also not advisable always. It is against the principle of information hiding.

Enterectomy answered 22/9, 2012 at 19:47 Comment(2)
Though I agree with <quote>Making friends is also not advisable always.</quote> I definitely think <quote>It is against the principle of information hiding</quote> is wrong. Friendship does not break encapsulation in increases it. The alternative to friendship is to expose the data to more systems (which does break encapsulation). Friendship increases encapsulation at the cost of tightly coupling the friend and thus making it part of the interface. programmers.stackexchange.com/a/99595/12917Ablaze
I agree with that. But it generally depends upon the approach, the situation and the problem in hand. As in this one, friendship can easily be avoided.Enterectomy

© 2022 - 2024 — McMap. All rights reserved.