访问基类功能

JKS*_*JKS 11 c++ inheritance

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

class Derived : public Base
{
    private:
    using Base::foo;
};

int main()
{
   Derived d;
   d.foo();
}
Run Code Online (Sandbox Code Playgroud)

代码合法吗?声明using Base::foo位于派生类的私有部分中.所以调用d.foo()不应该编译,我是对的吗?

Che*_*Alf 5

对.

现在检查......

MinGW g ++ 4.4.1:

x.cpp:在函数'int main()'中:x.cpp:3:错误:'void Base :: foo()'不可访问
x.cpp:15:错误:在此上下文中

Visual C++ 10.0:

x.cpp(15):错误C2248:'Derived :: foo':无法访问类'Derived'中声明的私有成员
x.cpp(9):请参阅'Derived ::
foo'x.cpp(6)的声明:看'衍生'的宣言

Comeau Online 4.3.10.1:

在严格模式下,使用-tused,编译成功(但请记住,Comeau在线编译器没有链接).
编译启用C++ 0x扩展.

哎呀.而且Comeau几乎总是正确的!那么,关闭C++ 0x扩展,对于C++ 98/C++ 03:

在严格模式下,使用-tused,编译成功(但请记住,Comeau在线编译器没有链接).
用C++ 0x扩展编译DISabled.

哎呀!

嗯,你在我的大佬,正如他们在挪威所说的那样(字面翻译成英文).

我试着向Comeau报告.

编辑:既然Prasoon也回答了,引用了神圣标准,他的解释与我上面所写的内容相矛盾,嗯,好的,标准的......

§11.3/ 1"基类成员的访问权限可以在派生类中更改......"等等,这一点很清楚(不需要解释).并举一个具体的例子.规范性文本声明这相当于using声明.

干杯&hth.,

  • @Alf:这就是我的意思.OP的问题只是"这有用吗?" 答案是肯定的.也许一个更好的答案是"是的,但你不应该这样做",但@Prasoon Saurav的答案是正确的,我不认为应该投票. (3认同)

Pra*_*rav 1

标准第 11.2/4 节说

\n\n
\n

当在类 N 中命名时,成员 m 是可访问的,如果

\n\n

\xe2\x80\x94 m 作为 N 的成员是公共的,或者

\n\n

\xe2\x80\x94 m 作为 N 的成员是私有的,并且引用出现在 N 类的成员或友元中,或者

\n\n

\xe2\x80\x94 m 作为 N 的成员受到保护,并且引用出现在 N 类的成员或友元中,或者出现在从 N 派生的类 P 的\n 成员或友元中,其中 m 作为P 是私有的或受保护的,或者

\n\n

\xe2\x80\x94 存在 N 的基类 B ,可在引用点访问,并且 m 在类 B 中命名时可访问

\n
\n\n

然而该标准还指出

\n\n
\n

\xc2\xa711.3/1 “基类成员的访问权限可以在派生类中更改。

\n
\n\n

在您的代码中,派生类中的成员访问权限foo已更改。因此,代码不应编译,但这仍然是开放状态下的一个活跃问题 因此,一些编译器编译代码(Comeau 和 Intel C++),而 g++ 和 MSVC++(正确地)拒绝它。

\n

  • 我发誓您必须记住该标准;)我们始终感谢您的参考。 (3认同)
  • -1 g++ 和 msvc 不同意。神圣标准也是如此(@prasoon,我真的很讨厌人们引用 HS 中的内容,这似乎与我已经写过的内容相矛盾!<g>)。如果您刚刚阅读了 HS 中的下一段,即第 11.3 节,它完全致力于*访问声明*,“基类成员的访问可以在派生类中更改......效果是定义为等同于使用 `using` *qualified-id*" 的声明。这种访问声明是旧的标准前方式。`using` 是 C98 的方式。干杯, (2认同)