2011-10-06 11 views
0

두 파일 (A.cpp, Ah, B.cpp, Bh)의 동일한 클래스의 두 버전이 같은 이름을 갖지만 내부 구현이 다른 모든 파일에 있습니다 .다른 파일에 같은 이름의 다른 클래스 버전

제 아이디어는 #include에서 .h 파일의 이름을 변경하여 한 버전에서 다른 버전으로 전환하는 것입니다. 따라서 코드의 다른 내용을 변경하지 않아야합니다 (두 버전의 메소드가 동일한 서명을 가짐). 동일한 속성)

Ah와 Bh는 절대로 동시에 포함되지 않습니다.

문제는 파일을 포함하는 항목이 무엇이든 관계없이 항상 버전이 실행된다는 것입니다. 적어도 B.h를 포함 시켰을 때 (컴파일 타임에 표시되는 일부 코드 오류를 넣어서) 컴파일되었음을 알 수 있습니다.

이 작업을 수행 할 수 있습니까? 또는이 C++ 일부 규칙을 위반합니다? 나는 이것이 A.h와 B.h를 동시에 사용하지 않기 때문에 One Definition Rule을 위반해서는 안된다고 생각합니다.

+0

질문은 어떻게 객체 파일을 연결합니까? 포함을 조정하는 것만으로는 효과가 없습니다. – pmr

+2

B.h를 포함하고 B.o와 연결하면 문제가 없습니다. 너 어떻게 연결되어있어? 그러나 클래스의 API가 일관성이 있다면 A.h와 B.h는 동일해야합니다. 왜 다른가? –

+0

포함하는 헤더 파일은 연결하려는 실제 코드만큼 중요하지 않습니다. – Joe

답변

2

해결 방법은 이전 파일을 최종 실행 파일로 연결하지 않으려면 입니다. 그렇게하면 새 구현 만 사용할 수 있습니다.

0

헤더 파일이 동일하면 하나의 헤더와 두 개의 다른 구현 파일 만 있으면 더 쉽습니다. 그러면 문제가 줄어들어 올바른 개체 파일로 연결됩니다. 이것은 또한 헤더가 갈라지면 미묘한 버그가 발생할 가능성을 줄입니다.

물론 더 나은 솔루션은 빌드 시스템에 의존하지 않지만 템플릿과 같이 컴파일시에 코드를 변경하기 위해 언어 기능을 사용하는 것입니다.

+1

왜 템플릿이 더 좋을까요? 버전 관리는 빌드 시스템에서 가장 잘 관리되는 일반적인 경우입니다. –

+0

@James 두 가지 버전이 있지만 실제로 인터페이스의 두 가지 구현이 다르다는 인상은 없었습니다. – pmr

2

자주 수행 할 작업은 버전을 네임 스페이스에 mangle로 사용하는 것입니다. 다음 줄의 어떤 것 :

namespace Xyz_A { // In A.h 
// Define version A 
} 

namespace Xyz = Xyz_A; 

; B.h에서 대신 _B을 사용하십시오.

이 방법, 당신은 당신의 프로그램에 Xyz::...을 작성하지만, 외부 기호는 Xyz_A 또는 Xyz_B이 그 (것)들로 엉망이됩니다. 그러나 내 옵션에서 이것은 실제로 오류에 대한 보호입니다. 을 내 makefile에 배열하여 A.hB.h 사이를 전환하면 실행 파일이 적절한 라이브러리에 연결되고 다른 하나는 이 아닙니다.

+0

실제로 두 버전을 별도의 네임 스페이스에 넣으면 두 버전의 클래스를 동일한 실행 파일로 컴파일 할 수 있습니다. 빌드 프로세스를 간소화하는 것 외에도 버전간에 런타임 전환을 작성할 수 있습니다 (구성 파일 또는 명령 줄의 설정을 기반으로 클래스 버전을 선택하는 데 유용 할 수 있음). –

+0

@ AndréCaron 런타임시 네임 스페이스간에 전환 할 수 없습니다. 네임 스페이스는 순전히 컴파일 및 링크 시간 분석입니다. (저는 다른 네임 스페이스를 사용하여 오류를 감지합니다 : 하나의 버전에 대해 컴파일하고, 동적으로 또는 다른 방식으로 다른 것에 대해 컴파일하십시오.) –

+0

물론 그렇게 할 수 없습니다. 그러나'return (use_version_A ?: new Xyz_A :: Foo() : new Xyz_B :: Foo());와 같은 간단한 스위치를 작성할 수 있습니다. 빌드 프로세스로 전환하면이 작업을 수행 할 수 없습니다. –

0

헤더 파일과 일치하도록 올바른 라이브러리를로드해야합니다.

프록시 디자인 패턴을 조사하여 클래스 A와 B를 모두 포함 할 수 있도록 제안합니다. 그런 다음 프록시를 사용하여 런타임 중에 사용할 클래스 함수를 선택할 수 있습니다.

http://en.wikipedia.org/wiki/Proxy_pattern

관련 문제