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를 사용하고 있습니다.
세 가지 옵션이 있습니다.
소유권을 포기하십시오. 이렇게하면 함수 호출 후 동적 개체에 액세스하지 않고 로컬 변수가 남습니다. 개체가 수신자에게 전송되었습니다.
f(std::move(derived));
의 서명 변경
f
:void f(std::unique_ptr<Derived> const &);
변수 유형 변경 :
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>();
업데이트 : 또는 의견에서 권장하는대로 소유권을 전혀 이전하지 마십시오.
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 만 받아 들일 수 있기 때문에 이상 하며, 호출 수신자는 일반적으로 호출자의 수명 관리 선택에 신경을 쓰지 않아야합니다. 전달 은 이러한 사례의 엄격한 상위 집합을 다루며 호출자가 사용하는 수명 정책에 관계없이 “ 또는 ”를 수락 할 수 있습니다 .widget
unique_ptr
widget*
null
widget
나는 수락 된 대답의 옵션 # 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
'code' 카테고리의 다른 글
테이블에 계산 된 열을 어떻게 추가합니까? (0) | 2021.01.08 |
---|---|
"#! / bin / env"는 무엇을 의미합니까 (node.js 스크립트 맨 위에 있음)? (0) | 2021.01.08 |
`po`는`error : (0) | 2021.01.08 |
지연된 실행을 위해 Thread.Sleep 및 Timer 사용 비교 (0) | 2021.01.08 |
너겟 패키지 종속성 계층보기 (0) | 2021.01.08 |