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