2011-04-12 71 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