在派生 class 中使用指向基 class 的指针访问基 class 受保护的成员

Access base class protected members using pointers to base class in derived class

考虑以下代码:

#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指针直接访问基class的成员,但不能使用其他指针。
编译器是否将它们视为不同的实例化?

是的,这是预期的行为。基 class 的 Protected members 可以在派生 class 中访问,但只能通过 派生 class 类型的对象](或当前派生class的进一步派生class)(包括this)。这意味着您无法通过指向基 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)

一个更简单的测试例子:

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; }
};

在派生的 class D2 中,我们可以在 D2 实例中访问 Base::i,但不能在 Base 实例中访问,也不能在从 Base 而不是通过 D2.

派生的对象

其他方面很好的 [C++ 参考][protected] 说:

A protected member of a class Base can be accessed [...] 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).

上面的测试表明这里的措辞有点不准确¹ - 应该是 "only when operating on an object of its own type or one derived from it"。


¹ 或 GCC 不正确 - 我们真的应该为此检查标准。