2012-06-18 49 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;移出该功能。

注意:您可能需要也可能不需要完成第二部分,而这整个方法可能会也可能不会。我现在无法访问编译器。

我再次同意其他意见,这种设计是有缺陷的,它会令你头痛。