为什么 unique_ptr<Derived>隐式转换为 unique_ptr<Base>? [英] Why does unique_ptr<Derived> implicitly cast to unique_ptr<Base>?
问题描述
我编写了以下使用 unique_ptr
的代码,其中需要 unique_ptr
I wrote the following code that uses unique_ptr<Derived>
where a unique_ptr<Base>
is expected
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
和 unique_ptr
是不相关的类型和 unique_ptr
实际上不是从 unique_ptr
派生的,因此赋值不应该起作用.
and i expected this code to not compile, because according to my understanding unique_ptr<Base>
and unique_ptr<Derived>
are unrelated types and unique_ptr<Derived>
isn't in fact derived from unique_ptr<Base>
so the assignment shouldn't work.
但是多亏了一些魔法,它才起作用,我不明白为什么,或者即使这样做是安全的.谁能解释一下?
But thanks to some magic it works, and i don't understand why, or even if it's safe to do so. Can someone explain please?
推荐答案
您正在寻找的神奇之处在于转换构造函数 #6 这里:
The bit of magic you're looking for is the converting constructor #6 here:
template<class U, class E>
unique_ptr(unique_ptr<U, E> &&u) noexcept;
它允许从一个即将到期的 std::unique_ptr
if 隐式构造一个 std::unique_ptr
删除者为清楚起见):
It enables constructing a std::unique_ptr<T>
implicitly from an expiring std::unique_ptr<U>
if (glossing over deleters for clarity):
unique_ptr::pointer
可隐式转换为 pointer
也就是说,它模仿隐式原始指针转换,包括派生到基类的转换,并且安全地执行您期望的™(在生命周期方面 - 您仍然需要确保可以多态删除基类型).
Which is to say, it mimicks implicit raw pointer conversions, including derived-to-base conversions, and does what you expect™ safely (in terms of lifetime – you still need to ensure that the base type can be deleted polymorphically).
这篇关于为什么 unique_ptr<Derived>隐式转换为 unique_ptr<Base>?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!