code

unique_ptr을 기본 클래스로 가져 오는 함수에 대한 인수로 파생 클래스에 대한 unique_ptr

codestyles 2021. 1. 8. 08:14
반응형

unique_ptr을 기본 클래스로 가져 오는 함수에 대한 인수로 파생 클래스에 대한 unique_ptr


기본 클래스 를 사용하는 unique_ptr함수에서 파생 클래스 를 사용하려고합니다 unique_ptr. 다음과 같은 것 :

class Base {};

class Derived : public Base {};

void f(unique_ptr<Base> const &base) {}


unique_ptr<Derived> derived = unique_ptr<Derived>(new Derived);
f(derived);

이 대답을 올바르게 이해 하면 이 코드가 작동하지만 다음과 같은 컴파일 오류가 발생합니다.

오류 C2664 : 'f': 매개 변수 1을 'std :: unique_ptr <_Ty>'에서 'const std :: unique_ptr <_Ty> &'로 변환 할 수 없습니다.

IntelliSense : "std :: unique_ptr <Derived, std :: default_delete <Derived >>"에서 "const std :: unique_ptr <Base, std :: default_delete <Base >>"로의 적절한 사용자 정의 변환이 없습니다.

내가 f취하도록 변경 하면 unique_ptr<Derived> const &derived잘 작동하지만 내가 원하는 것은 아닙니다.

내가 뭘 잘못하고 있니? 이 문제를 해결하려면 어떻게해야합니까?

Visual Studio 2012를 사용하고 있습니다.


세 가지 옵션이 있습니다.

  1. 소유권을 포기하십시오. 이렇게하면 함수 호출 후 동적 개체에 액세스하지 않고 로컬 변수가 남습니다. 개체가 수신자에게 전송되었습니다.

    f(std::move(derived));
    
  2. 의 서명 변경 f:

    void f(std::unique_ptr<Derived> const &);
    
  3. 변수 유형 변경 :

    std::unique_ptr<base> derived = std::unique_ptr<Derived>(new Derived);
    

    또는 물론 :

    std::unique_ptr<base> derived(new Derived);
    

    또는:

    std::unique_ptr<base> derived = std::make_unique<Derived>();
    
  4. 업데이트 : 또는 의견에서 권장하는대로 소유권을 전혀 이전하지 마십시오.

    void f(Base & b);
    
    f(*derived);
    

가능한 해결책은 인수 유형을 a로 변경하고 대신 Base const*전달하는 derived.get()것입니다. 거기에 소유권의 더 전송이없는 unique_ptr const<Base>&(그리고이 unique_ptr수정되지 않는 경우), A를 변경하는 것은 그래서 Base const*의미를 변경하지 않습니다.


Herb Sutter는 Smart Pointer Parameters 에서 스마트 포인터 인수를 길게 전달하는 방법에 대해 설명 합니다. 링크 된 기사에서 발췌 한 내용은 다음과 같은 정확한 상황을 나타냅니다.

a를 전달하는 것은를 통해 호출 코드에서 수명이 관리되는 const unique_ptr<widget>&하나 null또는 a 만 받아 들일 수 있기 때문에 이상 하며, 호출 수신자는 일반적으로 호출자의 수명 관리 선택에 신경을 쓰지 않아야합니다. 전달 은 이러한 사례의 엄격한 상위 집합을 다루며 호출자가 사용하는 수명 정책에 관계없이 또는 ”를 수락 할 수 있습니다 .widgetunique_ptrwidget*nullwidget


나는 수락 된 대답의 옵션 # 1을 가지고 있었고 여전히 동일한 컴파일 오류가있었습니다. 한 시간 넘게 벽에 머리를 부딪 혔는데 마침내 깨달았습니다.

class Derived : Base {};

대신에

class Derived : public Base {};

ReferenceURL : https://stackoverflow.com/questions/17473900/unique-ptr-to-a-derived-class-as-an-argument-to-a-function-that-takes-a-unique-p

반응형