持有派生类指针的unique_ptr转基类unique_ptr遇转换错误求助
解决std::unique_ptr派生类到基类的赋值编译错误
错误原因
编译报错的核心问题有两点:
- 在
Stack类内部定义makeGreenStack函数时,GreenStack仅存在前向声明,编译器尚未确认它是Stack的派生类,因此无法完成std::unique_ptr<GreenStack>到std::unique_ptr<Stack>的向上转换。 std::make_unique<T>要求模板参数T是完整类型(类的完整定义必须可见),前向声明的GreenStack不满足这一条件,直接在Stack类内部调用std::make_unique<GreenStack>本身就是非法的。
解决方法
将makeGreenStack的实现移到GreenStack类的完整定义之后(类外实现),这样既能满足std::make_unique对完整类型的要求,也能让编译器识别派生关系,允许智能指针的向上转换。
修改后的完整代码:
class Stack { public: explicit Stack(double initial_weight) : weight_(initial_weight) {} // 仅声明静态函数,不定义 static std::unique_ptr<Stack> makeGreenStack(double initial_weight); bool operator<(const Stack& rhs) const { return weight_ < rhs.weight_; } virtual ~Stack() = default; protected: double weight_; }; class GreenStack:public Stack { public: explicit GreenStack(double initial_weight): Stack(initial_weight){} ~GreenStack() = default; }; // 在GreenStack完整定义后实现静态函数 std::unique_ptr<Stack> Stack::makeGreenStack(double initial_weight) { // 可直接返回,无需中间变量,编译器会自动处理向上转换 return std::make_unique<GreenStack>(initial_weight); }
额外优化
如果不需要中间变量,直接返回std::make_unique<GreenStack>的结果即可——当派生关系明确时,std::unique_ptr<GreenStack>可以隐式转换为std::unique_ptr<Stack>,无需手动调用std::move。
内容的提问来源于stack exchange,提问作者Dhiraj
相关产品推荐
相关产品推荐

