请考虑以下代码:
#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;
}
似乎可以使用this
指针直接访问基类的成员,而不是其他指针。
编译器是否将它们视为不同的实例化?
答案 0 :(得分:4)
是的,这是预期的行为。可以在派生类中访问基类的Protected members,但只能通过 派生类(或当前派生类的进一步派生类)的类型的对象(包括{ {1}})。这意味着您无法通过指向基类的指针访问受保护的成员。
只能访问类Base的受保护成员
1)...
2)由Base派生的任何类的成员,但仅限于 对从Base派生的类型的对象进行操作(包括 此)
答案 1 :(得分:0)
一个更简单的测试示例:
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; }
};
在派生类D2
中,我们可以访问Base::i
实例中的D2
,但不能访问Base
实例中的Base
,也不能访问源自{D2
的实例1}}不通过Base
。
反之亦然[C ++参考] [受保护]说:
类
Base
的受保护成员可以由派生自Base
的任何类的成员访问,但仅限于在对类型的对象进行操作时才能访问this
(包括setClass("student", slots=list(name="character", age="numeric", GPA="numeric") ) setMethod("show", "student", function(object) { cat(object@name, "\n") cat(object@age, "years old\n") cat("GPA:", object@GPA, "\n") } )
)。
上面的测试表明,这里的措辞有点不准确 - 它应该只有在“对自己类型的对象或从它派生的对象上进行操作时才会读”。
¹或GCC不正确 - 我们应该检查这个标准。