c++ - 为什么 unique_ptr<Derived> 隐式转换为 unique_ptr<Base> ?

标签 c++ templates inheritance unique-ptr

我编写了以下使用 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 here :

template<class U, class E>
unique_ptr(unique_ptr<U, E> &&u) noexcept;

它可以构建 std::unique_ptr<T>隐式地从过期的std::unique_ptr<U> if(为了清晰起见,忽略了删除器):

unique_ptr<U, E>::pointer is implicitly convertible to pointer

也就是说,它模仿隐式原始指针转换,包括派生到基的转换,并安全地执行您所期望的™(就生命周期而言 - 您仍然需要确保可以多态删除基类型) .

关于c++ - 为什么 unique_ptr<Derived> 隐式转换为 unique_ptr<Base> ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58181090/

相关文章:

python - 继承和聚合类属性

c++ - fatal error mysql.h :No such file or directory during compilation

c++ - 为什么我必须通过this指针访问模板基类成员?

Javascript 继承 - this.element 在子类中未定义

c++ - 使用具有派生类值的基类函数

c++ - 如果不是抽象则调用基类方法

c++ - 解析 C++ 中的结构并在其中搜索值

c++ - std::sort 做了很多不必要的交换

c++ - 不能将规范与 fmt 库混合

c++ - 可变参数模板的未声明标识符