2012-06-18 58 views
0

​​:C++命名空間

#include <iostream> 

    namespace ns {  // want to access this globally 
     class A ; 
    } 

    class ns::A { 
    public: 
    int x1; 
    char s1[128]; 
    }; 

    int main() 
    { 
    int doit(); 
    //using namespace ns; 

     ns::A a; 

     a.x1= 2; 

     std::cout << "pre " << a.x1 << "\n" ; 
     doit(); 
     std::cout << "post " << a.x1 << "\n" ; 
    } 

ns_call.cpp

namespace ns { 
    class A; 
    } 

    class ns::A { 
    public: 
    int x1; 
    char s1[]; 
    }; 

    using namespace ns; 

    int 
    doit() 
    { 
     extern ns::A a; 

     a.x1= 100; 
    } 
在ns.cpp

,一個類被命名空間內declard。 該類定義如下。

班級中的變量將被全球訪問。這個 是命名空間的目標。

ns_call.cpp然後訪問該類的成員x1。

2檔在Fedora中被用gcc編譯5.4.1確定14 運行輸出是:

pre 2 
post 2 

我的預期 '後100',因爲我想訪問INT X1 A類 全球。

+3

這沒有鏈接:'未定義的'a'參考(它在'main'中聲明,不是全局聲明)。 –

+0

這是違反ODR的 - ns_capp.cpp中'ns :: A'的定義與ns.cpp中的定義不同。 – ildjarn

+0

移動「ns :: A a;」增加6條線。它的作品。 –

回答

3

沒有extern,namespace或前瞻性聲明似乎意味着你認爲他們的意思。

如果你想介紹一個可以被我的多個翻譯單元訪問的名字(當你說「全局」時你的意思是什麼),你把這些定義放在一個頭文件中,並且從你想要的任何地方使用它。

你實際上做的是在每個翻譯單元(例如,在每個CPP文件中)中一遍又一遍地引入class A。充其量,這是對ODR的違反。

1

我只是要幫助你解決你的問題,而你絕對必須聽取關於ODR(一個定義規則)的其他答案並修復你的設計。

在​​文件中,您必須將行ns::A a;移出main()函數。將它放在文件範圍內(例如在main之前)。另外,在ns_call.cpp文件中,也將行extern ns::A a;移出該功能。

注意:您可能需要也可能不需要完成第二部分,而這整個方法可能會也可能不會。我現在無法訪問編譯器。

我再次同意其他意見,這種設計是有缺陷的,它會令你頭痛。