访问基类功能

时间:2010-11-29 16:09:52

标签: c++ inheritance

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

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

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

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

3 个答案:

答案 0 :(得分: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':无法访问私有   在“派生”类中声明的成员
          x.cpp(9):见'Derived :: foo'的声明           x.cpp(6):见'Derived'的声明

Comeau Online 4.3.10.1:

  

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

糟糕。而且Comeau几乎总是正确的!好吧,关闭C ++ 0x扩展,对于C ++ 98 / C ++ 03:

  

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

<强>糟糕!

嗯,正如他们在挪威所说的那样(你直接翻译成英文),你是我的傻瓜。

我会尝试向Comeau报告。

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

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

干杯&amp;第h。,

答案 1 :(得分:1)

第11.2 / 4节中的标准说

  

如果

,则在N类中命名时可以访问成员m      

- 作为N的成员m是公开的,或

     

- 作为N的成员的m是私有的,并且引用发生在N类的成员或朋友中,或

     

- 作为N的成员的m受到保护,并且引用发生在N类的成员或朋友中,或者发生在   从N派生的P类的成员或朋友,其中作为P的成员的m是私有的或受保护的,或

     

- 存在可在参考点访问的N的基类B,并且在B类中命名时可访问m

然而标准也说

  

§11.3/ 1“可以在派生类中更改基类成员的访问权限。

在您的代码中,成员foo的访问权限已在派生类中更改。所以代码不应该编译,而是this is still an active issue with open status所以一些编译器编译代码(Comeau和Intel C ++),而g ++和MSVC ++(正确)拒绝它。

答案 2 :(得分:0)

using是此示例中的命名空间声明(与命名空间指令相对)。它不是方法声明,因为您似乎打算将其用作。

方法foo()Base课程中公开,并且仍然可以在Derived课程中访问。

您似乎打算让foo()类的Base无法访问。虽然可能有一种方法可以做到这一点(我不知道,我从来没有理由尝试过它),我建议这指出了你的继承逻辑的错误,你可能想考虑重新设计我们的课程。

如果您的Derived类不会表现为Base类,则它不应该从Base类继承。