2012-03-28 2 views
1

C 라이브러리 FILE *을 래핑하는 템플릿을 얼마 동안 가지고 있습니다. 이는 FILE *에 대한 래퍼 클래스에 대한 공유 포인터를 상당히 고전적으로 구현 한 것입니다. 내 자신의 사용자 지정 공유 포인터를 사용하는 추론은 FILE *로 작동하는 레거시 코드의 드롭 인 대체를 수행 할 수 있도록 일부 C 라이브러리 FILE * free 함수에 대해 무료 함수 대체를 제공하는 것입니다.템플릿을 사용하여 런타임 다형성을 해결하는 데 도움이 필요합니다.

내가 가지고있는 구현은 소유 된 FILE *이 삭제 된 것을 보장하는 내부 래퍼를 사용합니다. RAII.

그러나 마지막 FILE * 홀더가 제거되었을 때 닫히지 않고 기본 플러시 *를 플러시하려는 경우를 처리하기 위해 유사한 시스템을 만들 필요가 있습니다. 말하자면, 나는 원래 보장 된 타입의 열린 FILE *을 갖고 있지만 FILE *의 소유되지 않은 복사본을 다른 객체에 넘기려고합니다.이 객체는 그것이 마지막 인스턴스가 파괴 될 때, &을 닫으 려하지 않고 FILE *을 잘라 버리므로 기본 FILE *을 열린 상태로 유지하지만 스트림의 내용은 디스크로 플러시됩니다 (유효한 내용 만 반영하는 파일 크기).

나는 이것을 컴파일 타임 다형성을 위해 간단하게 해결했다. 하지만 런타임 polymorphism을 제공하는 방법이 필요합니다. 그리고 실제로이 시나리오에 다른 단계의 간접 참조를 넣고 싶지는 않습니다 (즉, 자동 닫기 또는 자동 플러시 파일에 다형 포인터를 사용하는 경우). * wrapper, 나는 황금색이 될 것이지만, 나는 지금 가지고있는 것과 같은 깊이를 유지하고 커스텀 공유 포인터 구현 내부의 다형성을 숨기고 싶다.) 나는이있는 경우

기본적으로 : 분명히

template <class WrapperT> 
class FilePointerT 
{ 
public: 
    // omitted: create, destroy, manipulate the underlying wrappered FILE* 
private: 
    WrapperT * m_pFileWrapper; 
    ReferenceCount m_rc; 
} 

을, 세부 사항의 톤은 생략. 이 객체의 마지막 하나가 삭제 될 때, 마지막 m_pFileWrapper를 삭제한다고 말하면 충분합니다 (실제로이 코드를 다시 작성하면 boost :: shared_ptr을 사용합니다).

에 관계없이, 여기 진짜 문제는 내가 그 WrapperT 다를 수 FilePointerT <WrapperT>을하는 방법에 대한 난처한 상황에 빠진하고 있지만, 그들이 것처럼 다음 코드에서 사용할 수있는 모든, 결국, 그들이있는 (동일한 WrapperT의 구현이 있기 때문에, 제로? 나는 그 가능성이있는 WrapperT에 대한 어떤 FilePointerT <WrapperT>를 저장할 수있는 선언 할 수있는 것. FilePointerT의 구조와 인터페이스 (본질적으로 pimpl)에

에 영향을 미치거나, 어떻게 특정 WrapperT를 제공 할 수 있도록 FilePointerT의 정의를 변경할 수 있습니까?

답변

0

필자가 한 일은 FilePointer 클래스에 래퍼를 포함시키는 것이 었습니다.

class FilePointer 
{ 
public: 
    // create using a file wrapper (which will handle policy issues) 
    FilePointer(FileWrapper * pfw) : m_pFileWrapper(pfw) { } 

protected: 
    FileWrapper * m_pFileWrapper; // wrapper has close/flush policy 
    ReferenceCount m_references; // reference count 
}; 

그런 다음 파일 포인터 위양 래퍼로 실제 작업을하고 래퍼 필요한 정책을 구현하고, 코드는 파일 포인터 (들)을 소비 쓸 수 있습니다.

분명히 다른 방법이 있지만, 그게 제가 한 일입니다.

3

간단히 std::shared_ptr<FILE *, deleter_function>을 사용할 수 없습니까? 무료 기능을위한 일반적인 오버로드를 제공합니다. 재미있는 템플릿 말라키는 아닙니다.

+0

이 솔루션을 살펴보면 ... – Mordachai

2

type erasure을 사용하면 모든 버전의 FilePointerT를 투명하게 처리 할 수 ​​있습니다. 위의 포스터에서 언급했듯이 shared_ptr 접근법도 있습니다. 실제로 deleter는 shared_ptr 서명에도 포함되지 않으므로 형식을 일정하게 유지하면서 deleter를 변경할 수 있습니다.

+0

+1은 유형 삭제를위한 것으로, 결국 'shared_ptr'솔루션이 작동하는 방법과 이유입니다. –