2012-02-26 39 views
6

下面的代碼不會在GCC編譯:C++和注入基本名稱

namespace One{ 
    class A{ 
    }; 
}; 

namespace Two{ 
    class A{ 
     public: 
     void what(){ 
      cout << "Two::A says what!" << endl; 
     } 
    }; 

    class B : public One::A{ 
     public: 
     B(){ 
      A xx; 
      xx.what(); 
     } 
    }; 

}; 

,它給:

gccbug.cpp: In constructor ‘Two::B::B()’: 
gccbug.cpp:23: error: ‘class One::A’ has no member named ‘what’ 

現在,有人告訴我,這是正確的行爲(由於注射基地一個的名稱::一個製造的A指的是一個:: A)。然而,這段代碼在C#中編譯(當然,在改變了一些東西之後),所以這似乎是C++特有的。

我想知道的是..爲什麼?是否有將基本名稱「One :: A」注入爲「A」的特定目的?

+6

僅供參考,C#!= C++。我不確定你爲什麼要比較這兩個 – 2012-02-26 11:37:42

+0

我不能肯定地說(我現在沒有我的副本),但作爲一個旁白,關於爲什麼C++語言被設計成它的方式的問題在Stroustrup的一本名爲「The Design and Evolution of C++」的書中經常被回答。 – 2012-02-26 12:07:37

+0

@TonyTheLion,那是另一種類似c語言的編程語言,它具有「名稱空間」,我有權訪問編譯器。我並不是說只有「一種真實的方式」,這是正確的,但這看起來並不直觀,至少在這個例子中。 – kamziro 2012-02-26 12:28:13

回答

3

我能想到的唯一理由是,在C++中,你很可能指的是基類名在構造函數初始化列表,像這樣:

namespace Two { 

    /*...*/ 

    class B : public One::A { 
    public: 
    B():A() 
    { 
     /*...*/ 
    } 
    }; 
} 

課程的目的則是不同的從你的例子中,因爲你實際上在構造函數中聲明瞭一個局部變量,而在我的例子中,A()指的是由於繼承而在class B的定義中隱含的A類型的對象。

但是,我的例子的情況更可能發生,所以我猜他們認爲我們不要求在這種情況下明確命名空間。因此,對沒有名稱空間的A的引用被解釋爲引用基類,而不是任何其他名爲A的類,即使它與B的聲明位於同一名稱空間中。

+0

啊,是的,這實際上是有道理的。儘管我確實說這有點像「黑客」。 – kamziro 2012-02-26 12:35:43

3

是否有將基本名稱「One :: A」注入爲「A」的特定目的?

是的。它是如此,你可以這樣寫:

namespace N 
{ 
    class A 
    { 
     A *a; 
    }; 
} 

沒有注射名的,你寫N::A *a這是不是很好。

請注意,這是因爲注入的名稱,下面幾行被允許:

A::A *a1; //ok 
A::A::A *a2; //ok 
A::A::A::A *a3; //ok 
A::A::A::A::A *a4; //ok 
//and so on 

Online demo

+0

這與提問者解釋的情況不同嗎?在最初的例子中,'B類'在一個命名空間內,但它派生自的類在另一個命名空間中。 – jogojapan 2012-02-26 11:51:13

+1

@jogojapan但是'class B'繼承了它的基類中的所有名字,包括基類本身的注入名字。作爲內部作用域,它隱藏了周圍名稱空間的名稱。 – 2012-02-26 12:22:42

+0

@波佩森是的。我只是指出上面的例子並不完全說明這一點。在上面的例子中,對類「A」的唯一引用與類本身的聲明在同一個名字空間內。你不需要爲此注入名字。 – jogojapan 2012-02-26 12:29:25

0

通過與One::資格Anamespace一個範圍添加A,所以編譯器會在那裏尋找它的名字解析。

+0

但是在構造函數中聲明的類型'A'的對象還沒有被'One ::'限定。它被解釋爲屬於'namespace One',儘管'class B'本身的聲明實際上在'namespace Two'內。 – jogojapan 2012-02-26 11:48:50