2011-09-26 2 views

답변

5

템플릿 기반 클래스에서 사용할 때 pimpl 이디엄은 실제로 아무것도 숨기지 않지만 C++ 11 이동 의미론을 사용하면 덜 우려 할 만하지만 비 던져 스왑을 쉽게 작성할 수 있습니다.

+1

+1 완전히 잊어 버렸습니다. 던지지 않는 청결 함 외에도 스왑의 효율성 이점이기도합니다. 이것은 불투명 한 클래스가 pimpled 클래스처럼 쉽게 움직일 수 없기 때문에 이동 의미에 대해서도 적용됩니다. –

+1

이것이 유일한 실질적인 이점 인 것 같습니다. –

1

대규모 프로젝트의 경우 번역 단위를 단독으로 분리하면 여드름이 생길 수 있습니다. 엄격하게 pimpl 관용구하지 않을 수 있습니다

// main interface 

template <typename> struct MyImpl; 

class TheInterface 
{ 
    MyImpl<int> * pimpl; 
}; 

// implementation 

#include "MyImpl.hpp" // heavy-weight template library 

// TheInterface implementation 
+0

'TheInterface'가 템플릿 인 경우에는 작동하지 않습니다. 맞습니까? –

+1

기본 템플릿의 구현을 클래스 정의에서 분리하고 해당 TU에서 명시 적 인스턴스화를 사용할 수는 있지만 멋지지는 않습니다. 그래도 작은 수의 고정 된 템플릿 매개 변수가있는 경우에만 의미가 있습니다. 그러나 그렇지 않다면 어쨌든 전체 발목 아이디어가 적절하지 않을 수 있습니다. –

+0

큰 프로젝트에서 pimpl 관용구는 프로젝트를 더 크게 만드는 좋은 방법입니다. 결과는 C++로 코딩 된 일종의 C# 프로그램이며,이 경우에는 pimling 대신 C#으로 직접 포팅하는 것이 더 낫습니다. 미리 컴파일 된 헤더가 이미 처리 된 경우에는 pimpl 관용구의 컴파일 속도가 향상되지 않습니다. ** pimpl은 C++ ** –

1

Theres는 1 예,하지만에 대해 알고 보장 할만큼 유사하다 :이 템플릿으로도 사용할 수 있습니다. 그것은 타입 안전하지 않은 버전 위에 타입 안전 템플릿 래퍼를 갖는 것입니다.

class MapBase 
{ 
    public: 
    void* getForKey(const std::string & k); 
    void setForKey(const std::string & k, void * v); 
    ... 
}; 

template<typename T> 
class MyMap 
{ 
    public: 
    T* getForKey(const std::string &k) { return (T*)base_.getForKey(k); } 
    void setForKey(const std::string &k, const T* v) { base_.setForKey(k, T*v); } 
    private: 
    MapBase base_; 
}; 

지금 MyMap<T>의 사용은 MapBase의 내부에 노출 될 필요가 없습니다, 당신은 단지 그 기능의 내장 중 하나 구현을 얻는다. 또한 MapBase를 디커플링을 더욱 강력하게 만드는 추상 기본 클래스로 만드는 것도 고려해 볼 수 있습니다.

내가 말했듯이, 정확하게는 여드름이 아니지만 같은 방식으로 같은 문제가 해결 될 수 있습니다.

0

관용구를 약간 확장하면 어떤 경우에는 약간 벗어날 수 있다고 생각합니다. 템플릿에서 모든 작업이 반드시 템플릿 매개 변수에 의존해야하는 것은 아닙니다. 그래서 당신은 자신이 같은 pimpl 관용구, 뭔가를 사용하는 Impl 클래스에서 상속 할 수 있습니다 : 물론

struct FooPimpl; 

class FooImpl { 
    protected: 
    FooPimpl* pimpl; 
    public: 
    void myCommonInterfaceMethod(); 
}; 

template <typename T> class Foo : public FooImpl { 
    // stuff that depends on T 
}; 

,이 상황에 크게 의존한다. 하지만 템플릿 클래스 컨텍스트에서 작업하는 pimpl 관용구를 참조하십시오.

0

여전히 유용합니다. 자동 또는 공유 포인터를 고려해보십시오.이 포인터는 템플릿이며 PIMPL을 해결하고 구현하는 데 매우 유용합니다. 그것이 최선의 해결책인지 여부는 문제에 달려 있습니다.

컴파일러가 필요에 따라 인스턴스화하기 위해 템플릿에 헤더를 완전히 정의해야합니다.

템플릿의 구성원 및 인터페이스를 선언 한 다음 유형의 cpp 파일에서 전문화에 대한 필수 정의를 #include 수 있으며 거기에서 사용할 수 있습니다.

관련 문제