我有一个基类及其子类:
class Base { public: virtual void hi() { cout << "hi" << endl; } }; class Derived : public Base { public: void hi() override { cout << "derived hi" << endl; } };
尝试创建一个辅助函数,该函数创建Derived对象的唯一指针.
1)这个工作:
std::unique_ptr<Base> GetDerived() { return std::make_unique<Derived>(); }
2)但是,这个无法编译:
std::unique_ptr<Base> GetDerived2() { auto a = std::make_unique<Derived>(); return a; }
3)std :: move作品:
std::unique_ptr<Base> GetDerived3() { auto a = std::make_unique<Derived>(); return std::move(a); }
4)如果我创建一个Base实例,两者都有效:
std::unique_ptr<Base> GetDerived4() { auto a = std::make_unique<Base>(); return a; } std::unique_ptr<Base> GetDerived5() { auto a = std::make_unique<Base>(); return std::move(a); }
为什么(2)失败但其他人工作?
解决方法
std :: unique_ptr不可复制,只能移动.您可以返回std :: make_unique< Derived>的原因从声明为返回std :: unique_ptr< Base>的函数是从一个转换到另一个.
所以1)相当于:
std::unique_ptr<Base> GetDerived() { return std::unique_ptr<Base>(std::made_unique<Derived>()); }
由于从std :: make_unique返回的值是rvalue,因此返回值是move-construct.
对比2),相当于:
std::unique_ptr<Base> GetDerived2() { std::unique_ptr<Derived> a = std::make_unique<Derived>(); return std::unique_ptr<Base>(a); }
由于a是左值,因此返回值必须是复制构造的,并且std :: unique_ptr是不可复制的.
3)因为你将左值a转换为右值而起作用,并且返回值可以移动构造.
4)和5)工作,因为你已经有一个std :: unique_ptr< Base>并且不需要构造一个返回.