【问题标题】:Private inheritance: name lookup error私有继承:名称查找错误
【发布时间】:2011-08-03 19:50:57
【问题描述】:

我有以下无法编译的代码示例:

#include <stdio.h>

namespace my
{
    class base1
    { // line 6
    };

    class base2: private base1
    {
    };

    class derived: private base2
    {
    public:
        // The following function just wants to print a pointer, nothing else!
        void print(base1* pointer) {printf("%p\n", pointer);}
    };
}

gcc 打印的错误是:

test.cpp:6: 错误: `class my::base1' 无法访问

test.cpp:17: 错误:在此范围内 上下文

现在,我可以猜出问题出在哪里:查看print 的声明时,编译器看到base1 并认为:base1derived* this 的基类子对象,但你没有无法访问它!虽然我打算 base1 应该只是一个类型名称。

我如何在 C++ 标准中看到这是正确的行为,而不是编译器中的错误(我确信这不是错误;我检查过的所有编译器都是如此)?

我应该如何解决这个错误?以下所有修复都有效,但我应该选择哪一个?

void print(class base1* 指针) {}

void print(::my:: base1* 指针) {}

类 base1; 无效打印(base1* 指针){}


编辑:

int main()
{
    my::base1 object1;
    my::derived object3;
    object3.print(&object1);
}

【问题讨论】:

  • 你能发布 main() 吗?
  • 很好的例子表明私有继承与组合完全不同!

标签: c++ class-members name-lookup private-inheritance


【解决方案1】:

您要查找的部分是 11.1。它建议使用 ::my::base1* 来解决这个问题:

[ 注意:在派生类中,基类名称的查找将找到注入的类名称,而不是声明它的范围内的基类名称。在声明它的范围内,注入的类名可能比基类的名称更难访问。 ——尾注]

[ Example:
class A { };
class B : private A { };
class C : public B {
A *p;
// error: injected-class-name A is inaccessible
:: A * q ;
// OK
};

【讨论】:

  • 你能解释一下什么是注入类名吗?
  • 第 9 章,第 2 点:在看到类名后立即将类名插入到声明它的范围内。类名也被插入到类本身的范围内;这被称为注入类名。出于访问检查的目的,注入的类名被视为公共成员名。类说明符通常称为类定义。一个类在看到其类说明符的右大括号后被认为已定义,即使它的成员函数通常尚未定义。
  • 如果您对所提供的答案感到满意,@anatolyg,您能否将其标记为已接受,以便其他人也能看到?
猜你喜欢
  • 2017-08-13
  • 2013-08-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-07
  • 1970-01-01
  • 2016-04-12
相关资源
最近更新 更多