2012-06-18 4 views
0

ns.cpp: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 затем получает доступ к 1 члену класса, x1.

2 файла были составлены в порядке с GCC 5.4.1 в Fedora 14. Выход пробег:

pre 2 
post 2 

Я ожидал, что 'сообщение 100', потому что я хотел получить доступ к Int x1 в классе А во всем мире.

+3

Это не ссылка: 'неопределенная ссылка на 'a'' (она объявлена ​​внутри' main', а не глобально). –

+0

Это нарушение ODR - определение ns :: A' в ns_capp.cpp отличается от определения в ns.cpp. – ildjarn

+0

Переместите «ns :: A a;» до 6 строк. Он работает тогда. –

ответ

3

Ни один из extern, namespace s или передовые декларации, по-видимому, означают то, что вы думаете о них.

Если вы хотите ввести имя, к которому можно получить доступ, мои множественные единицы перевода (что вы, кажется, имеете в виду, когда говорите «глобально»), вы помещаете эти определения в заголовочный файл и #include этот заголовок откуда угодно использовать его.

То, что вы на самом деле делаете, вводит class A снова и снова в каждой единицы перевода (например, в каждом файле CPP). Это является нарушением ODR в лучшем случае.

1

Я просто помогу вам исправить вашу проблему, в то время как вы абсолютно должны прислушаться к другим ответам об ODR (One Definition Rule) и исправить свой дизайн.

в файле ns.cpp, вам необходимо переместить строку ns::A a; из main(). Поместите его в область файла (например, прямо до main.) Кроме того, в файле ns_call.cpp также перемещайте строку extern ns::A a; из функции.

Примечание: вам может потребоваться или не нужно выполнять вторую часть, и весь этот метод может работать или не работать. У меня нет доступа к компилятору прямо сейчас.

Опять же я должен согласиться с другими комментариями, что этот дизайн испорчен, и он будет вызывать головные боли.

Смежные вопросы