에서 cppreference ,
T
가 일부 base 의 파생 클래스인 경우 암시적으로B
다음std::unique_ptr<T>
으로 변환할 수 있습니다.std::unique_ptr<B>
원시 포인터와 마찬가지로 다형성이 작동하려면 분명히 그래야 합니다. 내 질문은 스마트 포인터가 일반적으로 여기 에서 볼 수 있는 포인터로 변환할 수 없다면 런타임 다형성을 허용하기 위해 스마트 포인터가 사용하는 메커니즘은 무엇입니까? 내 생각은 생성자에서 또는 std::make_unique<>()
/ std::make_shared<>()
객체의 내부 포인터가 이 변환에 사용 된다는 것입니다 . 그러나 이러한 암시적 변환이 다른 곳에서는 허용되지 않는 경우 스마트 포인터를 구성할 때 get()을 호출하지 않아도 되는 이유는 무엇입니까?
매우 간단한 예로서 다음 테스트를 생각해 냈습니다.
#include <iostream>
#include <memory>
class Base
{
public:
virtual ~Base() = default;
virtual void foo() const { std::cout << "Base foo() called." << std::endl; }
};
class Derived : public Base
{
public:
virtual void foo() const override { std::cout << "Derived foo() called." << std::endl; }
};
void bar(Base* pBase)
{
std::cout << "bar() called." << std::endl;
pBase->foo();
}
int main()
{
std::unique_ptr<Base> pObject { std::make_unique<Derived>() }; // Implicit conversion here, why no call to get()?
// bar(pObject); // Can't be converted, so we have to call get()
bar(pObject.get());
}
내 질문은 스마트 포인터가 일반적으로 여기에서 볼 수 있는 포인터로 변환할 수 없다면 런타임 다형성을 허용하기 위해 스마트 포인터가 사용하는 메커니즘은 무엇입니까?
스마트 포인터는 이러한 변환을 가능하게 하도록 명시적으로 설계되었습니다. std::unique_ptr
생성자 문서 에서 볼 수 있듯이 :
template< class U, class E >
unique_ptr( unique_ptr<U, E>&& u ) noexcept; (6)
이 오버로드는 이 목적을 위해 생성됩니다.
이 생성자는 다음이 모두 true인 경우에만 오버로드 해결에 참여합니다.
a) unique_ptr<U, E>::pointer는 암시적 으로 포인터 로 변환 가능 합니다.
b) U는 배열 유형이 아닙니다.
c) Deleter가 참조 유형이고 E가 D와 동일한 유형이거나 Deleter가 참조 유형이 아니고 E가 D로 암시적으로 변환 가능합니다.
강조는 나의 것이다. 따라서 파생 클래스에 대한 포인터는 암시적으로 기본으로 변환할 수 있으므로 이 생성자 오버로드는 이러한 변환을 가능하게 합니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다