5
#include <iostream>
using namespace std;
class A
{
protected:
    int a;
};
class B : public A
{
public:
    int func(A* p)
    {
        cout << p->a;
    }
};

I really cannot understand why I cant access to 'a' by 'p->a'.

Is there anyway to access p's member 'a' in class B, without changing 'protected' to 'public'?

4
  • 1
    AFAIK, you should be able to access a, so what compiler and os are you using? And, what messages are produced when you compile this? Commented Sep 12, 2011 at 15:23
  • Can you access just a instead of p->a? Commented Sep 12, 2011 at 15:23
  • error C2248: 'A::a' : cannot access protected member declared in class 'A' Commented Sep 12, 2011 at 15:24
  • I am currently using Visual Studio 2010... Commented Sep 12, 2011 at 15:24

3 Answers 3

10

On this topic, the C++03 standard states (emphasis mine):

11.5 Protected member access

1 When a friend or a member function of a derived class references a protected nonstatic member function or protected nonstatic data member of a base class, an access check applies in addition to those described earlier in clause 11. Except when forming a pointer to member (5.3.1), the access must be through a pointer to, reference to, or object of the derived class itself (or any class derived from that class) (5.2.5).

What you are doing here, however, is trying to access through a pointer to the base class, which is illegal. If you change the signature to

int func(B* p) // instead of A*

you will find that it now compiles normally.

This is also the reason why you can access a without trouble from inside class B: the access is made through the implicit pointer this, which is of type B* (the derived class again). If you tried this:

A* parent = static_cast<A*>(this);
int x = parent->a; // Does not compile!

You would find that it won't compile, for the very same reason.

The converse also applies: if you downcast the pointer p to a B* you can access the protected member just fine:

class A
{
public:
    // Added virtual destructor so that the class acquires a vptr,
    // making dynamic_cast possible.
    virtual ~A() {};
protected:
    int a;
};

class B : public A
{
public:
    int func(A* p)
    {
        // Now if we downcast p to B* we can access a just fine
        // Of course if p does not actually point to a B, the
        // program will have undefined behavior
        int x = dynamic_cast<B*>(p)->a;
    }
};
Sign up to request clarification or add additional context in comments.

1 Comment

Thx a lot Jon!! C++ is getting more interesting than I thought before :)
2

Using p->a would only let you access public variables of A. Since a is a protected variable, you should use cout << a, since a is inherited in class B.

I think you could use cout << p->a by friending class B.

Or by using a pointer to B instead of a pointer to A, as Jon noted.

4 Comments

It seems like friend also does not work :( I tried #include <iostream> using namespace std; class A { protected: int a; }; class B : public A { friend class A; public: int func(A* p) { cout << p->a; } };
It's the other way around: class A: {friend class B; ...}
There is no public and protected "version" of the variable. The compiler simply does not let you access non-public members through a pointer to the base class.
@djeidot: The answer is still misleading and incomplete. a is not the same as p->a, and in fact you can access p->a from the parameter by e.g. doing a dynamic_cast<B*>(p)->a (although this comes with its own set of pitfalls).
1

Ahh, this is a good question. First, let me start off by saying B is NOT a friend of A, and therefore does not have access to A's privates (or protected's) through an "A" view of the object. Even though we are in the scope of class B, we cannot just go around looking at A's privates (or protected's).

HOWEVER, B does have an a. And it does have access to it, because it is declared a protected member of A. But the only way to see int a inside of a B, is to get it from a B view of an object.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.