Reputation: 67211
I have a simple class as below
class A {
protected:
int x;
};
class B : public A {
public:
int y;
void sety(int d) {
y = d;
}
int gety() {
return y;
}
};
int main() {
B obj;
obj.sety(10);
cout << obj.gety();
getch();
}
How can I set the value of the protected
instance variable A::x
from an instance of the derived class B
without creating an instance of class A
.
EDIT: Can we access the value of A::x
using the object of B? Like obj.x
?
Upvotes: 20
Views: 92291
Reputation: 7
You can't call obj.x
directly because you might have the same variable name in your base
and derived
classes. And that will always point to the derived class data member. To access the base
data member you need to add the scope resolution operator A::x
in case of the identical variable name.
Upvotes: 0
Reputation: 31435
Note that B does not have FULL access to A::x. It can only access that member through an instance of a B, not anything of type A or deriving from A.
There is a workaround you can put in:
class A
{
protected:
int x;
static int& getX( A& a )
{
return a.x;
}
static int getX( A const& a )
{
return a.x;
}
};
and now using getX, a class derived from A (like B) can get to the x member of ANY A-class.
You also know that friendship is not transitive or inherited. The same "workaround" can be made for these situations by providing access functions.
And in your case you can actually provide "public" access to the x through your B by having public functions that get to it. Of course in real programming it's protected for a reason and you don't want to give everything full access, but you can.
Upvotes: 2
Reputation: 62975
B
is an A
, so creating an instance of B
is creating an instance of A
. That being said, I'm not sure what your actual question is, so here's some code that will hopefully clarify things:
class A
{
protected:
int x;
};
class B : public A
{
public:
int y;
int gety() const { return y; }
void sety(int d) { y = d; }
int getx() const { return x; }
void setx(int d) { x = d; }
};
int main()
{
B obj;
// compiles cleanly because B::sety/gety are public
obj.sety(10);
std::cout << obj.gety() << '\n';
// compiles cleanly because B::setx/getx are public, even though
// they touch A::x which is protected
obj.setx(42);
std::cout << obj.getx() << '\n';
// compiles cleanly because B::y is public
obj.y = 20;
std::cout << obj.y << '\n';
// compilation errors because A::x is protected
obj.x = 84;
std::cout << obj.x << '\n';
}
obj
can access A::x
just as an instance of A
could, because obj
is implicitly an instance of A
.
Upvotes: 18
Reputation: 9773
A::x
is protected, so not accessible from outside, neither as A().x
or B().x
. It is however accessible in methods of A
and those directly inheriting it (because protected, not private), e.g. B
. So, regardless of semantics B::sety()
may access it (as plain x
or as A::x
in case of shadowing by a B::x
or for pure verbosity).
Upvotes: 1
Reputation: 4805
You can just refer to it simply as x
in class B
For example:
class B : public A
{
public:
...
void setx(int d)
{
x=d;
}
};
Upvotes: 0