问题
Consider the following code:
#include <iostream>
using std::endl;
using std::cout;
template<typename T>
class B{
protected:
T value;
B* ptr;
public:
B(T t):value(t), ptr(0){}
};
template<typename T>
class D: public B<T>{
public:
void f();
D(T t):B<T>(t){}
};
template<typename T>
void D<T>::f(){
cout << this->value << endl; //OK!
this->ptr = this;
cout << this->ptr->value << endl; //error! cannot access protected member!!
B<T>* a = this;
cout << a->value <<endl; //error! cannot access protected member!!
}
int main(){
D<double> a(1.2);
a.f();
return 0;
}
It seems that the member of the base class can be directly accessed using this
pointer, but not the other pointers.
Does the compiler consider them as different instantiation?
回答1:
Yes, this is expected behavior. Protected members of base class can be accessed in the derived class, but only via an object of a type that is the derived class (or the further derived class of current derived class) (including this
). That means you can't access protected members via a pointer to base class.
A protected member of a class Base can only be accessed
1) ...
2) by the members of any class derived from Base, but only when operating on an object of a type that is derived from Base (including this)
回答2:
A simpler test example:
class Base
{
protected:
int i;
};
class D1 : public Base
{
};
class D2 : public Base
{
int a(Base& b) { return b.i; } // error
int a(D1& d) { return d.i; } // error
int a(D2& d) { return d.i; }
};
In the derived class D2
, we can access Base::i
in a D2
instance, but not in a Base
instance, nor in an object that derives from Base
not through D2
.
The otherwise-good [C++ Reference][protected] says:
A protected member of a class
Base
can be accessed [...] by the members of any class derived fromBase
, but only when operating on an object of a type that is derived fromBase
(includingthis
).
The test above suggests that the wording is slightly inaccurate there¹ - it should read "only when operating on an object of its own type or one derived from it".
¹ or that GCC is incorrect - we should really check the standard for this.
来源:https://stackoverflow.com/questions/43756254/access-base-class-protected-members-using-pointers-to-base-class-in-derived-clas