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

孤街浪徒 提交于 2019-12-02 07:58:52

问题


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 from Base, but only when operating on an object of a type that is derived from Base (including this).

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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!