예상되는 unique_ptr<Derived>
위치 를 사용하는 다음 코드를 작성했습니다.unique_ptr<Base>
class Base {
int i;
public:
Base( int i ) : i(i) {}
int getI() const { return i; }
};
class Derived : public Base {
float f;
public:
Derived( int i, float f ) : Base(i), f(f) {}
float getF() const { return f; }
};
void printBase( unique_ptr<Base> base )
{
cout << "f: " << base->getI() << endl;
}
unique_ptr<Base> makeBase()
{
return make_unique<Derived>( 2, 3.0f );
}
unique_ptr<Derived> makeDerived()
{
return make_unique<Derived>( 2, 3.0f );
}
int main( int argc, char * argv [] )
{
unique_ptr<Base> base1 = makeBase();
unique_ptr<Base> base2 = makeDerived();
printBase( make_unique<Derived>( 2, 3.0f ) );
return 0;
}
나의 이해에 따라 때문에 내가 컴파일하지에이 코드를 기대 unique_ptr<Base>
하고하는 것은 unique_ptr<Derived>
관련이없는 종류와 unique_ptr<Derived>
에서 파생 된 사실에없는 unique_ptr<Base>
할당이 작업 안 그렇게.
그러나 어떤 마술 덕분에 효과가 있으며, 왜, 또는 그렇게하는 것이 안전한지 이해하지 못합니다. 누군가 설명해 주시겠습니까?
답변
당신이 찾고있는 마법의 비트는 변환 생성자 # 6입니다 여기 :
template<class U, class E>
unique_ptr(unique_ptr<U, E> &&u) noexcept;
std::unique_ptr<T>
만료되는 std::unique_ptr<U>
if (명확하게하기 위해 deleters에 광택 있음) 에서 암시 적으로 구성 할 수 있습니다 .
unique_ptr<U, E>::pointer
묵시적으로pointer
즉, 파생-대-기반 변환을 포함하여 암시 적 원시 포인터 변환을 모방하고 예상 수명을 기준으로 안전하게 수행합니다 (여전히 기본 유형을 다형성으로 삭제할 수 있는지 확인해야 함).
답변
왜냐하면 std::unique_ptr
A 변환 등이있다 생성자
template< class U, class E > unique_ptr( unique_ptr<U, E>&& u ) noexcept;
과
이 생성자는 다음 사항이 모두 충족되는 경우에만 과부하 해결에 참여합니다.
a)
unique_ptr<U, E>::pointer
암시 적으로pointer
…
A Derived*
는 Base*
암시 적으로 변환 할 수 있으며이 경우 변환 생성자를 적용 할 수 있습니다. 그런 다음 원시 포인터처럼 암시 적 std::unique_ptr<Base>
으로 a를 변환 할 수 있습니다 std::unique_ptr<Derived>
. ( 의 특성으로 인해 std::unique_ptr<Derived>
생성을 위해서는 rvalue 여야합니다 .)std::unique_ptr<Base>
std::unique_ptr
답변
당신은 할 수 암시 적 구성체 std::unique_ptr<T>
에서 인스턴스 를 rvalue 의 std::unique_ptr<S>
때마다 S
로 변환입니다 T
. 이 # 6 생성자 예정이다 여기 . 이 경우 소유권이 이전됩니다.
귀하의 예에서는 rvalues 유형 std::uinque_ptr<Derived>
( r 값이 std::make_unique
rvalue 이기 때문에) 만 가지고 있으며,이를 값으로 사용할 때 std::unique_ptr<Base>
위에서 언급 한 생성자가 호출됩니다. std::unique_ptr<Derived>
따라서 문제 의 대상은 짧은 시간 동안 만 존재합니다. 즉, 대상이 생성 된 후 소유권이std::unique_ptr<Base>
객체 이후에 사용되는 객체 .