2011-04-12 74 views
13

我有下面的代码示例无法编译:私有继承:名称查找错误

#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: error: `class my::base1' is inaccessible

test.cpp:17: error: within this context

现在,我能猜到是什么问题是:在查看print的声明时,编译器看到base1并认为:base1derived* this的基类子对象,但您无权访问它!虽然我打算base1应该只是一个类型的名字。如何在C++标准中看到这是一个正确的行为,而不是编译器中的错误(我相信它不是一个bug;我检查过的所有编译器都表现如此)?

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

void print(class base1* pointer) {}

void print(::my:: base1* pointer) {}

class base1; void print(base1* pointer) {}


编辑:

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

你可以张贴在main()? – 2011-04-12 11:52:41

+0

很好的例子表明私人继承与组成完全不同! – curiousguy 2011-12-26 00:14:09

回答

12

你要找的部分是11.1。它建议使用::我:: BASE1 *来解决此问题:

[ Note: In a derived class, the lookup of a base class name will find the injected-class-name instead of the name of the base class in the scope in which it was declared. The injected-class-name might be less accessible than the name of the base class in the scope in which it was declared. — end note ]

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

你能解释一下注入类名是什么吗? – davka 2011-04-12 12:03:50

+1

第9章,第2点: 在看到类名后立即声明一个类名称。类名也被插入到类本身的范围中;这被称为注入类名称。为了进行访问检查,将注入的类名称视为公共成员名称。类说明符通常被称为类定义。尽管其成员函数一般尚未定义,但类被视为在其类类说明符的左括号之后被定义。 – 2011-04-12 12:06:47

+1

如果您对提供的答案感到满意,@anatolyg,请您将此标记为已接受,以便其他人也可以看到这一点? – 2011-04-12 12:29:27