Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can a derived class not access a protected member of its base class through a pointer to base?

This is the code:

class TestA
{
protected:
    int test=12;

public:
    TestA() {
        cout << "test a: " << test << endl;
    }
    ~TestA() {
    }
};

class TestB : public TestA
{   
public:
    TestB(TestA *testA) {
        cout << "test b: " << testA->test;
    }
    ~TestB() {
    }
};

int main ()
{
    TestA *pTestA=new TestA();
    TestB *pTestB=new TestB(pTestA);
}

I'm trying to access of a protected member using a pointer pointing to a TestA type object (thus, an instance of TestA). TestB is also derived from TestA

Why I can't access to it? Is it accessible only "within" the class where I need it? Not outside using pointer/direct declarations?

like image 376
markzzz Avatar asked Aug 02 '16 10:08

markzzz


People also ask

Can a derived class directly access a protected member of its base class?

Protected members in a class are similar to private members as they cannot be accessed from outside the class. But they can be accessed by derived classes or child classes while private members cannot.

Can you access the public members of the derived class through a pointer of the base class?

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.

How are protected members of class accessed in the derived class?

Protected members that are also declared as static are accessible to any friend or member function of a derived class. Protected members that are not declared as static are accessible to friends and member functions in a derived class only through a pointer to, reference to, or object of the derived class.

How does a derived class can get access privilege for a private member of the 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. In the following example, class D is derived publicly from class B . Class B is declared a public base class by this declaration.


1 Answers

When public inherite from the base class, its protected members become the derived class' protect members, which could be accessed in derived class' member functions. But they could only be accessed through the derived class itself (and its derived classes), can't be accessed through the base class. So you can't access member test via pointer of TestA, but it'll be fine to access it via pointer of TestB.

The standard gives some illustrative samples for this. [class.protected]/1:

(Only keep a part of the example code)

An additional access check beyond those described earlier in Clause [class.access] is applied when a non-static data member or non-static member function is a protected member of its naming class ([class.access.base])114 As described earlier, access to a protected member is granted because the reference occurs in a friend or member of some class C. If the access is to form a pointer to member ([expr.unary.op]), the nested-name-specifier shall denote C or a class derived from C. All other accesses involve a (possibly implicit) object expression ([expr.ref]). In this case, the class of the object expression shall be C or a class derived from C. [ Example:

class B {
protected:
  int i;
};

class D1 : public B {
};

class D2 : public B {
  void mem(B*,D1*);
};

void D2::mem(B* pb, D1* p1) {
  pb->i = 1;                    // ill-formed
  p1->i = 2;                    // ill-formed
  i = 3;                        // OK (access through this)
  B::i = 4;                     // OK (access through this, qualification ignored)
}

— end example ]

I'm not sure about your design's intent, making TestB friend of TestA would be a straightforward solution.

like image 177
songyuanyao Avatar answered Nov 08 '22 09:11

songyuanyao