11

下一个例子的编译:

class A
{
  public:
    void foo()
    {
    }
};

class B : private A
{
  public:
    using A::foo;
};

int main()
{
    typedef void (B::*mf)();
    mf func = &B::foo;

    B b;
    (b.*func)();
}

失败并出现下一个错误:

main.cpp||In function ‘int main()’:  
main.cpp|18|error: ‘A’ is an inaccessible base of ‘B’  
main.cpp|18|error:    in pointer to member function conversion

我知道 A 不是 B 的可访问基础,但我正在使用using关键字。它不应该允许访问函数 foo 吗?

标准中的哪些相关段落阻止了上述内容的编译?

4

3 回答 3

6

由于fooinB继承自A&B::foo因此与 相同&A::foo,并且具有类型void (A::*)()。当你写

typedef void (B::*mf)();
mf func = &B::foo;

您正在尝试从 转换void (A::*)()void (B::*)(). 由于B从您那里私下继承A不能这样做。

于 2011-09-15T08:38:22.230 回答
3

成员的访问A由第 11 章“成员访问控制”管理,但指针到成员的转换在 4.11 中涵盖。特别是,4.11/2 声明当您无法将 a 转换为 aT A::*时,T B::*您无法将 a 转换B*为 a A*

这是问题的轻微变化:

class A
{
  public:
    void foo()
    {
    }
};

class B : private A
{
  public:
    using A::foo;
};

int main()
{
    typedef void (A::*amf)();
    typedef void (B::*bmf)();
    amf func = &A::foo;
    bmf f2 = static_cast<bmf>(func);
}

我们仍在谈论相同的功能。B::foo失败的不是名称查找(using负责处理),而是类型B::fooisvoid A::*()无法转换为void B::*().

于 2011-09-15T08:41:49.340 回答
-1

我已经简化了问题。主要问题如下:

int main() 
{ 
    &B::foo; 
}

在这里,我试图访问在 A 类中定义并私下继承的 foo 的地址。因此它给出了编译错误。

仅使用导入函数。它不会更改 foo 的访问说明符。

于 2011-09-15T11:35:38.573 回答