【问题标题】:Access base class protected members using pointers to base class in derived class在派生类中使用指向基类的指针访问基类受保护的成员
【发布时间】:2017-10-01 01:28:23
【问题描述】:

考虑以下代码:

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

【问题讨论】:

  • 这和模板有什么关系?

标签: c++ protected access-rights


【解决方案1】:

是的,这是预期的行为。基类的Protected members 可以在派生类中访问,但只能通过派生类(或当前派生类的进一步派生类)类型的对象(包括this )。这意味着您不能通过指向基类的指针访问受保护的成员。

类 Base 的受保护成员只能被访问

1) ...

2) 由从 Base 派生的任何类的成员,但仅当 对从 Base 派生的类型的对象进行操作(包括 这个)

【讨论】:

  • 您的描述并不完全相同 - 引用表明在对 不同 派生类的对象进行操作时,也可以从一个派生类的成员访问它.你能确认一下吗?
  • @TobySpeight 答案已修改。关于不同的派生类,进一步派生类也可以。
【解决方案2】:

一个更简单的测试示例:

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中,我们可以在D2实例中访问Base::i,但不能在Base实例中访问,也不能在从Base派生的对象中访问,而不是通过D2

否则很好的 [C++ 参考][受保护] 说:

Base 的受保护成员可以被从Base 派生的任何类的成员访问[...],但只有在对派生自Base 的类型的对象进行操作时(包括this)。

上面的测试表明这里的措辞有点不准确¹ - 它应该读作“仅在对自己类型的对象或派生的对象进行操作时”。


¹ 或者 GCC 不正确 - 我们真的应该检查这个标准。

【讨论】:

    猜你喜欢
    • 2014-09-12
    • 2016-12-07
    • 1970-01-01
    • 2014-08-27
    • 2016-07-31
    • 2011-01-27
    • 2015-02-04
    • 2019-01-20
    • 2012-08-29
    相关资源
    最近更新 更多