2010-11-20 2 views
2

"불순한 가상 함수"는 진단 목적으로 (http://www.gotw.ca/gotw/031.htm에 설명 된대로) 구현 된 순수 가상 함수를 의미합니다.이것은 불순한 가상 함수를 구현하는 합법적 인 방법입니까?

을 구현하는 산뜻한 방법은하는 것입니다 :

class Foo 
{ 
public: 
    ... 
    virtual void Bar() = 0; 
}; 

void Foo::Bar() { assert(false); } 

을하지만이 클래스가 순수 가상 메소드를 가지고 특히 들어 가지 지루한입니다. 또한 누군가가 실수로 해당 구현을 추가하지 않고 새로운 순수 가상 함수를 추가하지 않도록하는 것은 어렵습니다.

class Foo 
{ 
public: 
    ... 
    virtual void Bar() = 0 
    { 
     assert(false); 
    } 
}; 

하지만 C++ 표준은 명시 적으로합니다 (ISO C++ 2003 표준 섹션 10.4/2)을 허용하지 :

이상적으로 내가 뭘하려는 것입니다.

대신 다음과 같은 해킹을 생각해 보았습니다. 해당 Foo.cpp 소스 파일에서 다음

#ifndef ABSTRACT_METHOD 
#define ABSTRACT_METHOD = 0 
#endif 

class Foo 
{ 
public: 
    ... 
    virtual void Bar() ABSTRACT_METHOD; 
}; 

과 : 그것은 하나의 컴파일 된 구현을 얻을 수 있도록

#define ABSTRACT_METHOD { assert(false); } 

#include "Foo.h" 

... 

Foo.h 헤더합니다.

그렇게 합법적일까요?

+0

음, 소스 파일에';'가 쓰여질 것입니다 ... –

+0

@Oli Charlesworth : 사실, 그렇지만 본질적으로 잘못된 점이 있습니까? 어쨌든 후행하는';'에 대한 책임을 매크로 정의로 옮김으로써 쉽게 피할 수 있습니다. – jamesdlin

+1

@james : 예, 저는 이것이 컴파일러 오류라고 생각합니다. 나는 그것이 쉽게 해결할 수 있다는 것을 알고 있지만 이것은 부수적 인 관찰 이었지만 비판은 아니었다. –

답변

4

아니요, 유효하지 않습니다. 하나의 정의 규칙은 클래스가 여러 번역 단위의 프로그램에 여러 개의 정의를 가질 수 있지만 이러한 정의는 모두 동일한 토큰 시퀀스 (3.2/5)로 구성되어야한다고 말합니다. ABSTRACT_METHOD은 매크로 교체 이전의 사전 처리 토큰이지만 충분하지 않습니다.

따라서 .cpp 파일은 헤더가 포함 된 다른 .cpp와 같은 프로그램에서 유효하게 사용할 수 없습니다.

+1

Darn, 그건 내가 두려워했던거야. 표준의 관련 섹션을 가리켜 주셔서 감사합니다. 나는 __declspec (dllimport) 대'__declspec (dllexport)'속성이 기술적으로 표준 관점에서 합법적이지 않다는 것을 의미한다고 생각합니다. – jamesdlin

+1

@jamesdlin : 기술적으로 네,'__declspec'은 예약 된 이름입니다. 표준을 포함하고있는 프로그램이 엄격하게 준수하지 않는 한 관련이 있습니다. 이 프로그램은 Microsoft가 정의한 C++의 사투리에서 여전히 유효 할 수 있습니다. 그리고 문서가 ODR을 (명시 적으로 또는 함축적으로) 완화하면 괜찮습니다. –

+0

아마도 중간 개발은 (ABSTRACT_METHOD가) 내부 개발 빌드에서 다른 것들이되도록 (컴파일러가 불완전한 파생 클래스를 잡도록), 그것이 다른 곳의 스텁 구현이되게하는 것일 수도 있습니다. – jamesdlin

0

유효한지 여부는 알 수 없습니다. 그러나 클래스 사용자가 소스 파일에서 파생 클래스를 선언하면 컴파일러에서 이 표시되지 않으므로 Bar()을 해당 파생 클래스에 구현해야한다고 강요하지 않습니다. 나는 이것이 혼자서 이렇게하지 않을 이유라고 생각한다.

+0

그건 중요한 지적입니다. 클래스를 별도의 파일로 분리하기 때문에 코드베이스에서는 문제가되지 않습니다.또 다른 접근법은 매크로의 구현 버전을 정의하고 다양한 추상 기본 클래스 헤더를 포함하며 다른 것을 수행하지 않는 단일의 별도 소스 'impureVirtualStubs.cpp' 파일을 갖는 것입니다. – jamesdlin

관련 문제