2012-01-06 3 views
1

У меня есть пространство имен, в котором я хотел бы определить класс. Класс довольно сложный, поэтому я бы скорее определил его в отдельном файле заголовка, но даже самый простой код дает мне ошибку «неопределенной ссылки».Как использовать класс, определенный в отдельном заголовке в пространстве имен

main.cpp

#include <iostream> 
namespace A { 
    #include "C.hpp" 
} 

int main() 
{ 
    A::C foo; 
    std::cout << foo.member << std::endl; 
    return 0; 
} 

C.hpp

class C { 
    public: 
    C(); 
    int member; 
} 

C.cpp

C::C() 
{ 
    this->member = 10; 
} 

Когда я бегу g++ C.cpp main.cpp я получаю «main.cpp :(. Текст + 0x10): неопределенная ссылка на ошибку «A :: C :: C()». Я полагаю, что это определение конструктора C :: C() как-то не так, но я не знаю, как его исправить.

+1

Ну, ваши определения неправильны ... –

+1

Я собираюсь предположить, что вы это сделали, потому что вы столкнулись с конфликтами именования. На этом этапе я просто хочу сказать: «Надеюсь, вы изучили свой урок о пренебрежении пространствами имен при создании классов. –

ответ

0
namespace A { 
    #include "C.hpp" 
} 

Это очень странно, что нужно сделать.

В этом месте все объявлено в заголовке внутри пространства имен, которое называется A; в частности, он дает вам объявление A::C, которое представляет собой другой класс для ::C, который вы получаете, когда включаете заголовок без окружающего пространства имен.

Вы предоставили определение для ::C::C(); но main.cpp требует определения для A::C::C(), так как это класс, который он использует. Это не определено нигде, следовательно, ошибка.

Либо поместить C должным образом в namespace A путем перемещения имен в файл заголовка (и исправить C.cpp использовать это пространство имен), или избавиться от namespace A.

4

Вы должны определить конструктор C «s внутри пространства имен A тоже:

namespace A 
{ 
    C::C() 
    { 
     this->member = 10; 
    } 
} 
+4

И, следовательно, вам нужно решить, какое пространство имен принадлежит классу впереди. Нет' namespace A { #include "C.hpp"} 'от одного пользователя и' namespace B {#include "C.hpp"} 'от другого. Если класс и его члены полностью не определены в заголовке, хотя я не рекомендую, чтобы либо , поскольку два пользователя будут иметь два разных класса, которые имеют идентичные определения.Если пользователь не любит пространство имен, выбранное автором класса, они могут писать 'namespace A {typedef HorridNamespace :: CC;}' или ' namespace A {using HorridNamespace :: C;} '. –

+0

Я вижу.Так что я либо должен определить весь класс в заголовке, либо включить его за пределы пространства имен? Что считается лучшим подходом, если класс не будет много использовать за пределами пространства имен? – user1134621

+0

@Steve: или просто 'namespace A = HorridNamespace'. –

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