From http://www.parashift.com/c++-faq-lite/basics-of-inheritance.html#faq-19.5
A member (either data member or member function) declared in a protecte
You are not accessing protected function in your derived class, you are trying to overload it and promote from protected to public. This is a forbidden action, you only can hide functions in derived class, e.g. overload protected function as a private.
Accessing protected function means call it from some member of a class:
class Y : public X
{
public:
void call() {
fun();
}
}
or like you call it by objX.fun();
is also correct.
One solution is to add friend class Y
to X.
In void Y::call ()
X objX;
objX.fun ();
// here you're trying to access the protected member of objX , this
/current object of Y
doesn't contains objX
as it's base object , they both are different objects. That is why you can't access its member.
you can make Y
friend of X
as a solution told by @anycom.
Edit: what I mean is, from inside Y
(which is inherited from X
) , you can simply call protected/public members of "it's" base class X
i.e you're accessing it's base members simply. But That doesn't means you can now access the protected members of all objects of type X
, since you're trying to access those members from outer scope of class X
i.e via object of X
. You know all these rules but it seem you did too much thinking 0_o
Well, if friend
is ok, then this angle may as well be ok:
#include <iostream>
class X {
private:
int var;
protected:
virtual void fun() {
var = 10;
std::cout << "\nFrom X" << var;
}
static void Fun(X& x) {
x.fun();
}
};
class Y : public X {
private:
int var;
public:
virtual void fun() {
var = 20;
std::cout << "\nFrom Y" << var;
}
void call() {
fun();
X objX;
objX.fun(); /* << ne-ne */
Fun(objX); /* << ok */
}
};
Of course, be mindful of the type you pass to X::Fun
if you use this as-is.
See this example:
#include <iostream>
using namespace std;
class X {
private:
int var;
protected:
void fun ()
{
var = 10;
cout << "\nFrom X" << var;
}
};
class Y : public X {
private:
int var;
public:
void fun ()
{
var = 20;
cout << "\nFrom Y" << var;
}
void call ()
{
fun(); /* call to Y::fun() */
X::fun (); /* call to X::fun() */
X objX;
/* this will not compile, because fun is protected in X
objX.fun (); */
}
};
int main(int argc, char ** argv) {
Y y;
y.call();
return 0;
}
This yields
From Y20 From X10
Because you have overloaded the fun()
-method in Y, you have to give the compiler a hint which one you mean if you want to call the fun
-method in X by calling X::fun()
.
I think that the thing you are trying to do should looks like this:
#include <iostream>
using namespace std;
class X
{
private:
int var;
protected:
virtual void fun ()
{
var = 10;
cout << "\nFrom X" << var;
}
};
class Y : public X
{
private:
int var;
public:
virtual void fun ()
{
var = 20;
cout << "\nFrom Y" << var;
}
void call ()
{
fun ();
X::fun ();
}
};
That way you can invoke hiden member from your base class. Otherwise you have to add friend X as it was pointed in other post.