2014-09-11 4 views
2

스마트 포인터의 표준 컨테이너에서 사용할 때 전체 클래스 정의가 표시되는 것을 피할 수 있습니까? 예를 들어 나는 다음은 컴파일 할 수 없습니다unique_ptr의 표준 컨테이너에서 사용할 클래스를 선언하는 방법

#include <memory> 
#include <map> 
class Foo; 
class Bar { 
public: 
    Bar();  
    std::map<int, std::unique_ptr<Foo>> myMap; 
}; 

연타 컴파일러는 Bar를 컴파일 할 때 사용할 수 Foo의 전체 정의를 가지고 주장 것으로 보인다. Foo.h를 포함하지 않아도되는 기술이 있습니까?

EDIT1 :

 
error: invalid application of 'sizeof' to an incomplete type 'Foo': 
    static_assert(sizeof(_Tp) > 0, "default_delete can not delete incomplete type"); 

Edit2가 : 아니 그것은 is std::unique_ptr required to know the full definition의 중복이 아니다. unique_ptr을 사용하는 것만으로는 완전한 정의가 반드시 필요한 것은 아니지만 표준 컨테이너 안에서 사용하면 추가적인 주름이 생깁니다.

Edit3 : 가상 소멸자가있는 기본 클래스를 도입하여 원하는대로 (거의) 달성 할 수 있습니다. 그런 다음 기본 클래스에 대한 스마트 포인터 컨테이너가있는 클래스는 문제가 없으면 컴파일합니다. 기본 클래스에 기본 클래스가 있어야하며 기본 클래스가 완전히 표시되어야합니다. 컨테이너를 컴파일 할 때이 방식으로 모든 파생 클래스의 복잡성을 숨길 수 있습니다.

+2

'unique_ptr '은 (다른 유형자와 함께) 오타 일 수 있습니다. –

+0

[실제 코드를 표시하십시오.] (http://coliru.stacked-crooked.com/a/4b71c4045c07b58e). –

+0

무엇이 오류입니까? 코드의 오타를 수정할 수 있습니까? –

답변

-1

당신은 Foo 소멸자와 생성자를 public으로 만듭니다. 당신이 처음 게시물에서 전화하기 힘들 기 때문에 당신이 잘못을 가지고 있다면, 그들을 게시하시기 바랍니다. 다음 코드는 컴파일 :

#include <memory> 
#include <map> 

class Foo; 

class Bar { 
    public: 
     Bar() {}; 
     std::map<int, std::unique_ptr<Foo> > myMap; 
}; 

class Foo { 
    public: 
     Foo() {}; 
     ~Foo() {}; 

    }; 

int main() 
{ 
    Bar b; 
} 

편집이 : 엄격한 앞으로 선언이 스마트 포인터의 컨테이너를 컴파일하지 않을지라도 Forward declaration with unique_ptr?
Is std::unique_ptr<T> required to know the full definition of T?

+0

누구에게나 downvoted, 당신은 적어도 왜 말할 수 있습니까? –

+0

1. "작동"하는 코드를 추가해도 OP와 관련이없는 이유는 설명하지 않습니다. 2.public 생성자/소멸자는 그와 아무런 관련이 없습니다. 질문은 'unique_ptr'을 사용한 전체/앞으로 선언에 대한 것입니다 –

+0

내 에디팅 된 답변을 확인하십시오. 나는 그가 물었던 것을 회신하는 참고 문헌을 추가했다. 또한 그는 코드에서 오류가 발생하여 해결할 수 있다고 말합니다. 그리고 public 생성자/소멸자가 필요합니다. 그렇지 않으면 그 코드는 컴파일되지 않을 것입니다 (g ++ 4.8.2) –

0

, 여전히 가장 실용적인 해결할 수있다 : 이러한 다른 게시물을 확인 컨테이너로 사용자 클래스를 정의 할 때 완전한 클래스를 노출시키지 않아야합니다. public virtual distractor를 사용하여 기본 클래스를 소개하고이를 볼 수있게하십시오. 푸가 FooBase에서 파생 더 이상 바의 재 컴파일을 필요로하지 않을 것이다 푸에 자신의 헤더 파일 변경에 위치 bar.h

#include "foobase.h" 
#include <memory> 
#include <map> 
class Bar { 
    ... 
    std::map<int, std::unique_ptr<FooBase>> myMap; 
} 

에서 fooBase.h

class FooBase { 
    public virtual ~FooBase(); 
}; 

에서

.

관련 문제