使用std::shared_ptr实现多态遇类型绑定错误的技术问询
问题分析与解决
错误核心原因:std::shared_ptr<Child<int>>与std::shared_ptr<Base>属于不同类型,当你尝试将前者传给接受std::shared_ptr<Base>&的函数时,会隐式生成一个临时的std::shared_ptr<Base>对象,但非const左值引用无法绑定临时对象,这就是编译报错的根源。
以下是几种可行的解决方式:
方式一:修改函数参数为const引用
将Random::Foo的参数改为const std::shared_ptr<Base>&,临时对象可合法绑定到const引用,这是最简洁的方案(只要函数不需要修改传入的智能指针本身):
class Random { public: void Foo(const std::shared_ptr<Base>& ptr){} };
方式二:提前转换为基类智能指针
在调用Foo前,先将shared_ptr<Child<int>>隐式转换为shared_ptr<Base>,再传递给函数,适合函数必须接受非const引用的场景:
int main() { Random random; Child<int> derived; auto ptr = std::make_shared<Child<int>>(std::move(derived)); std::shared_ptr<Base> base_ptr = ptr; random.Foo(base_ptr); }
方式三:显式转换后传递
用std::static_pointer_cast显式转换后传递,效果与方式二一致,因为Child<int>明确继承自Base,该转换是安全的:
int main() { Random random; Child<int> derived; auto ptr = std::make_shared<Child<int>>(std::move(derived)); random.Foo(std::static_pointer_cast<Base>(ptr)); }
额外补充:如果只是需要创建一个默认的Child<int>对象,std::make_shared<Child<int>>()比std::make_shared<Child<int>>(std::move(derived))更简洁。
内容的提问来源于stack exchange,提问作者xyf
相关产品推荐
相关产品推荐

