18

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?

Elliott
  • 2,603
  • 2
  • 18
  • 35
Vijay
  • 65,327
  • 90
  • 227
  • 319

5 Answers5

17

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.

ildjarn
  • 62,044
  • 9
  • 127
  • 211
2

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.

CashCow
  • 30,981
  • 5
  • 61
  • 92
  • 1
    Entirely correct, but for a beginner you should contrast this with the behavior of `private:` – MSalters Mar 01 '11 at 14:46
  • See here if you are wondering why access to static protected member function is allowed but access to protected member is not allowed: https://stackoverflow.com/questions/16913451/why-calling-a-protected-static-method-in-derived-classes-is-allowed – Hari Apr 12 '23 at 20:05
1

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).

Tilman Vogel
  • 9,337
  • 4
  • 33
  • 32
0

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;
    }
};
Alex Deem
  • 4,717
  • 1
  • 21
  • 24
0

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.