2010-01-15 2 views
3

다소 학문적 인 질문이지만 단위 테스트를 작성하는 동안이 문제가 발생했습니다.C++/VS2005 : 두 개의 서로 다른 .cpp 파일에 동일한 클래스 이름 정의

내 단위 테스트 프레임 워크 (UnitTest ++)를 사용하면 구조물로 사용할 구조물을 만들 수 있습니다. 보통 이들은 파일의 테스트에 맞게 커스터마이징되어 있으므로 단위 테스트 파일의 맨 위에 놓습니다.

//Tests1.cpp 

struct MyFixture { MyFixture() { ... do some setup things ...} }; 

TEST_FIXTURE(MyFixture, SomeTest) 
{ 
    ... 
} 

//Tests2.cpp 

struct MyFixture { MyFixture() { ... do some other setup things, different from Tests1}}; 

TEST_FIXTURE(MyFixture, SomeOtherTest) 
{ 
    ... 
} 

그러나, 나는 최근에 발견 (와 VS2005 이상) 같은 이름을 사용하여 고정 구조체 이름을 지정할 때 다음 버전의 일 (그래서 지금 구조체의 두 가지 버전이 동일한 이름으로 존재하는) 것을 조용히 던져진. 이것은/W4 (가장 높은 경고 수준)로 설정된 컴파일러가 있고 경고가 나오지 않기 때문에 꽤 놀라운 것입니다. 나는 이것이 이름 충돌이고, 왜 네임 스페이스가 발명 되었는가를 추측하지만, 각각의 네임 테스트 픽스쳐를 별도의 네임 스페이스에 랩핑해야합니까? 나는 단지 내가 더 근본적인 것을 놓치지 않고 있는지 확인하고 싶다.

문제를 해결할 수있는 더 좋은 방법이 있습니까? 중복되는 심볼 오류 또는 다른 것을 보지 않아야합니까?

답변

8

익명 네임 스페이스에서 클래스를 고정 시키십시오. 각 파일에 대한 새 네임 스페이스를 만들고 이름을 지정하는 것보다 덜 불쾌 할 수 있습니다.

는 VS2005 및 CPP 장치에 액세스 할 수 없습니다하지만이 작동하지 않을 수 있습니다 ..

//Tests1.cpp 
namespace 
{ 
struct MyFixture { MyFixture() { ... do some setup things ...} }; 
} 

TEST_FIXTURE(MyFixture, SomeTest) 
{ 
    ... 
} 


//Tests2.cpp 
namespace 
{ 
struct MyFixture { MyFixture() { ... do some other setup things, different from Tests1}}; 
} 

TEST_FIXTURE(MyFixture, SomeOtherTest) 
{ 
... 
} 
+1

+1 이것은 익명의 네임 스페이스가 해결할 수있는 정확한 문제입니다 –

+0

두 개의 조명기 중 하나가 링커의 단어가 아닌 다른 것을 자동으로 덮어 쓸 것으로 예상됩니까? –

+0

잊어 버려 - 알 수 있습니다. 나는 틀린/멍청하게 구조체 타입에 이름 맹 글링 (mangling)이 적용될 것이라고 생각했기 때문에 링커는 그 차이를 알 수 있었다. –

0

을이 기본적으로 중복 데 리드 클래스, 헤더 파일에 정의 될 필요가 있다는 사실의 결과이다 각 객체 파일에있는 클래스의 정의. 따라서 C++ 연결을 처리 할 수있는 링커는 중복 클래스 선언을 함께 접어서 클래스가 한 번만 선언 된 것처럼 가장합니다.

링커가 여러 개체에 포함 된 단일 클래스와 여러 개체에서 같은 이름을 가진 여러 클래스를 구분할 수있는 방법이 없습니다.

이 문제를 해결하려면 네임 스페이스 (또는 더 나은 언어)를 사용해야합니다.

+0

@Kornel : 정적 사용은 링커가 볼 수없는 객체를 만드는 것 중 하나입니다. 링커는 볼 수없는 객체를 확실히 구분할 수 없습니다. 아니면 다른 점이 있습니까? –

+0

예, OP가 변수가 아니라 유형을 참조하고 있음을 알지 못했습니다. –

+0

예, 읽었습니다.그런 다음 익명의 네임 스페이스에 대해 읽어보십시오. –

2

컴파일러는 한 번에 하나의 컴파일 단위에서만 작동합니다. 이 파일은 소스 파일이 될 것이고 #include 파일 일 것입니다. 클래스가 다른 파일에 있기 때문에 충돌이 없습니다.

링커는 모든 것을 함께 저장하지만 클래스 정의에 대해서는 알지 못하므로 충돌이 발생하지 않습니다.

C에서 링커가 동일한 이름을 가진 두 개의 다른 함수를 가지고 있고 오류 메시지를 생성하는 것을 인식하는 것은 꽤 흔했습니다. C++의 인라인 함수와 템플릿을 사용하면 더 이상 그렇게 할 수 없습니다. 다른 컴파일 단위는 종종 동일한 함수의 중복을 포함하므로 링커는 동일하다고 가정합니다.