【问题标题】:error: 'void Base::output()' is protected within this context错误:“void Base::output()”在此上下文中受到保护
【发布时间】:2011-02-05 08:29:38
【问题描述】:

我对@9​​87654321@ 产生的错误感到困惑。 在 Derived::doStuff 中,我可以通过调用直接访问 Base::output。

为什么我不能在可以调用 output() 的同一上下文中创建指向 output() 的指针?

(我认为受保护/私有管理是否可以在特定上下文中使用名称,但显然这是不完整的?)

我写callback(this, &Derived::output);而不是callback(this, Base::output)是正确的解决方案吗?

#include <iostream>
using std::cout; using std::endl;

template <typename T, typename U>
void callback(T obj, U func)
{
  ((obj)->*(func))();
}

class Base
{
protected:
  void output() { cout << "Base::output" << endl; }
};

class Derived : public Base
{
public:
  void doStuff()
  {
// call it directly:
    output();
    Base::output();

// create a pointer to it:
//    void (Base::*basePointer)() = &Base::output;
// error: 'void Base::output()' is protected within this context
    void (Derived::*derivedPointer)() = &Derived::output;

// call a function passing the pointer:
//    callback(this, &Base::output);
// error: 'void Base::output()' is protected within this context
    callback(this, &Derived::output);
  }
};

int main()
{
  Derived d;
  d.doStuff();
}

编辑:我很想知道这在标准中的位置,但大多数情况下我只是想围绕这个概念来思考一下。我认为我的问题是callback 无权访问Derived 的受保护成员,但如果您将指针传递给它,它可以调用Derived::output。来自DerivedDerived 的受保护成员与来自BaseDerived 的受保护成员有何不同?

【问题讨论】:

  • +1,我很确定我最近阅读了答案但找不到它......希望一些当地的大师/标准能够启发我们。

标签: c++ access-modifiers


【解决方案1】:

简而言之,“因为标准是这样说的”。为什么?我不知道,我已经向几个标准人员发送了电子邮件,但还没有收到回复。

具体来说,11.5.1(来自C++0x FCD):

额外的访问检查 前面第 11 条中描述的那些 应用于非静态数据时 成员或非静态成员函数 是其命名的受保护成员 类 (11.2)114 如前所述, 访问受保护的成员是 因为引用发生而授予 在某个 C 类的朋友或成员中。 如果访问是形成一个指向的指针 成员 (5.3.1), 嵌套名称说明符应表示 C 或从 C 派生的类。所有其他 访问涉及(可能是隐式的) 对象表达式(5.2.5)。在这个 案例,对象的类 表达式应为 C 或类 源自 C。

编辑:

此外,您会看到您将代码更改为以下内容,根据标准规定,它将干净地编译(和运行):

void (Base::*derivedPointer)() = &Derived::output;

【讨论】:

    【解决方案2】:

    编辑:我不确定这是否是“标准中的这个在哪里?”问题或“为什么这样设计?”问题,这回答了后者(我没有标准本身的副本可玩)

    我相信这是因为具有 base 的受保护或朋友访问权限的函数将能够通过将函数指针传递给不应访问 base 的私有成员的方法来绕过访问保护。

    在此示例中,callback 无权访问 base,因此不应调用其私有函数之一。

    【讨论】:

    • 我认为我的问题是callback 也无权访问Derived 的受保护成员。来自DerivedDerived 的受保护成员与来自BaseDerived 的受保护成员有何不同?
    猜你喜欢
    • 2020-10-31
    • 2013-04-27
    • 1970-01-01
    • 2015-10-02
    • 1970-01-01
    • 2023-04-05
    • 2016-11-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多