gpt4 book ai didi

c++ - 错误 : 'void Base::output()' is protected within this context

转载 作者:太空狗 更新时间:2023-10-29 21:30:31 24 4
gpt4 key购买 nike

我对 following code 生成的错误感到困惑.在 Derived::doStuff 中,我可以通过调用直接访问 Base::output。

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

(我认为 protected/private 决定了你是否可以在特定上下文中使用名称,但显然这是不完整的?)

我编写 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 的 protected 成员,但它能够调用 Derived::output 如果你传递给它一个指针。来自 DerivedDerived 的 protected 成员与来自 BaseDerived 的 protected 成员有何不同?

最佳答案

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

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

An additional access check beyond those described earlier in Clause 11 is applied when a non-static data member or non-static member function is a protected member of its naming class (11.2)114 As described earlier, access to a protected member is granted because the reference occurs in a friend or member of some class C. If the access is to form a pointer to member (5.3.1), the nested-name-specifier shall denote C or a class derived from C. All other accesses involve a (possibly implicit) object expression (5.2.5). In this case, the class of the object expression shall be C or a class derived from C.

编辑:

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

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

关于c++ - 错误 : 'void Base::output()' is protected within this context,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2594151/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com