2011-08-17 6 views
0

네임 스페이스 사용 방법을 테스트하는 아주 작은 프로그램. 대형 제품에서는 ns.h가 네임 스페이스 인터페이스이고 ns.cpp가 구현이므로 3 파일로 나눕니다. 나는이 모든 것을 하나의 파일에 담을 수는 없다. 나는 위의 코드를 유지하고, 얻을 것이다 컴파일하면네임 스페이스가 정의되지 않았거나 재정의되는 이유는 무엇입니까?

//ns.h 
#ifndef MY_H 
#define MY_H 
namespace my 
{ 
    int a=1; 
    int b=0; 
    void test(); 
} 
#endif 

//ns.cpp 
#include <iostream> 
#include "ns.h" 

using namespace my; 
//my::a=1; 
//my::b=0; 
void my::test() 
{ 
    std::cout<<a<<std::endl; 
} 

//testns.cpp 
#include <iostream> 
#include "ns.h" 
int main() 
{ 
    std::cout<<my::b<<std::endl; 
    my::test(); 
} 

: 여기

코드입니다

testns.obj : error LNK2005: "int my::b" ([email protected]@@3HA) already defined in ns.obj 
testns.obj : error LNK2005: "int my::a" ([email protected]@@3HA) already defined in ns.obj 

을 나는 문의 #include 언급하면 ​​"ns.h"나는 얻을 것이다 정의되지 않은 오류.

D:\mfc\testns.cpp(5) : error C2653: 'my' : is not a class or namespace name 
D:\mfc\testns.cpp(5) : error C2065: 'b' : undeclared identifier 
D:\mfc\testns.cpp(6) : error C2653: 'my' : is not a class or namespace name 
D:\mfc\testns.cpp(6) : error C2065: 'test' : undeclared identifier 

이 작업 방법을 알고 있으면 친절하게 도와주세요. 고마워.

답변

2

머리말은 정의를위한 것이 아니라 선언을위한 것입니다. 네임 스페이스 문제와 관련이 없습니다.

//ns.h 
#ifndef MY_H 
#define MY_H 
namespace my 
{ 
    extern int a, b; // declared, not defined thanks to 'extern'. 
    void test(); 
} 
#endif 

//ns.cpp 
#include <iostream> 
#include "ns.h" 

int my::a=1; // now we provide the actual definitions. 
int my::b=0; 
void my::test() 
{ 
    std::cout << my::a << std::endl; 
} 

//testns.cpp 
#include <iostream> 
#include "ns.h" 
int main() 
{ 
    std::cout << my::b << std::endl; 
    my::test(); 
} 
+0

예,이 방법으로 작동하지만 왜 내 : : Cpp 파일에서 사용해야합니까? 패키지가 크면 많은 추가 작업이 필요합니다. 다른하실 말씀 있나요? – shangping

+0

난 그저 그런 식으로 했어. '네임 스페이스 my;을 사용하면''ns.cpp'에 도움이되지 않습니다. 왜냐하면 "여기에 이름을 찾을 수 없다면''내 이름을 찾아보십시오 '라고하기 때문입니다. "내가 뭔가 새로운 것을 정의한다면, 그것이 내'의 일부가되기를 바란다."라고 말하지 않는다. 하지만 예를 들어 다음과 같이 작성할 수 있습니다. '네임 스페이스 my {int a = 1; int b = 0; 무효 테스트() ...}'. 'testns에서.cpp' 물론'네임 스페이스 my을 사용할 수도 있고 아마도'my :: b를 사용합니다; 내 사용 :: test'. –

+0

감사합니다. Karl,이 말이 정말 합리적입니다. 좋은 대답! 마지막 방법은 내가 찾는 깔끔한 방법입니다! 많은 시간부터, 사람들은 몇몇 부호를 쓸지도 모르고 다 나는 그 (것)들에 많은 접두어를 추가하고 싶지 않는다. – shangping

1

은 헤더 파일에 변수를 정의하는 것은 표준적인 방법이 아닙니다. 그들은 #include 헤더를 찾을 때마다 다시 정의되어보고있는 링커 오류가 발생합니다. 당신은 소스 파일 사이의 변수를 공유해야하는 (그리고 거의 좋은 이유가이 거기의) 경우

, 당신은 헤더 파일에 extern에게 그들을 선언해야하고 소스 파일 중 하나에에게 그들을 정의 .

+0

에서 ns.h

#ifndef MY_H #define MY_H namespace my { extern int a; extern int b; void test(); } #endif 

을 변경합니다. 또한 정의되지 않은 오류가 발생합니다. – shangping

+0

예, 나는 cpp 파일에 my :: a, my :: b를 추가 할 것입니다. 그게 왜? – shangping

+0

이 답변도 정확 합니다만 어떻게 동시에 두 개의 답변을 승인 할 수 있습니까? 고맙습니다! – shangping

2

당신은 ns.h에서 두 변수 ab을 정의한 다음 헤더 파일은 두 개의 소스 파일에 포함되고있다. 변수가 ns.h을 포함하는 두 번역 단위 모두에 정의되므로이 값은 one definition rule을 위반합니다. 당신이해야 할 일은

가 헤더에 변수를 선언하고 는 하나의 소스 파일에에게를 정의합니다.

이 문제를 해결 내가 질문을 게시하기 전에 내가이 시도 ns.cpp

#include <iostream> 
#include "ns.h" 

using namespace my; 

int my::a=1; 

int my::b=0; 

void my::test() 
{ 
    std::cout<<a<<std::endl; 
} 
관련 문제