【发布时间】:2012-11-04 09:43:27
【问题描述】:
将派生类型的shared_ptr 传递给采用基类型shared_ptr 的函数的最佳方法是什么?
我通常通过引用传递shared_ptrs 以避免不必要的复制:
int foo(const shared_ptr<bar>& ptr);
但如果我尝试做类似的事情,这不起作用
int foo(const shared_ptr<Base>& ptr);
...
shared_ptr<Derived> bar = make_shared<Derived>();
foo(bar);
我可以使用
foo(dynamic_pointer_cast<Base, Derived>(bar));
但这似乎不是最理想的,原因有两个:
-
dynamic_cast对于简单的派生到基类转换来说似乎有点过分。 - 据我了解,
dynamic_pointer_cast创建了指针的副本(尽管是临时副本)以传递给函数。
有没有更好的解决方案?
后人更新:
原来是缺少头文件的问题。此外,我在这里尝试做的事情被认为是反模式。一般来说,
-
不影响对象生命周期的函数(即对象在函数的持续时间内保持有效)应该采用普通引用或指针,例如
int foo(bar& b). -
使用一个对象的函数(即给定对象的最终用户)应该按值获取
unique_ptr,例如int foo(unique_ptr<bar> b)。调用者应该std::move将值放入函数中。 -
延长对象生命周期的函数应按值采用
shared_ptr,例如int foo(shared_ptr<bar> b)。避免circular references 的通常建议适用。
详情请参阅 Herb Sutter 的Back to Basics talk。
【问题讨论】:
-
为什么要传递
shared_ptr?为什么没有 bar 的 const 引用? -
任何
dynamic转换仅用于向下转换。此外,传递派生指针应该可以正常工作。它将创建一个新的shared_ptr,具有相同的引用计数(并增加它)和一个指向基址的指针,然后绑定到 const 引用。但是,由于您已经在参考,因此我完全不明白您为什么要使用shared_ptr。拨打Base const&并致电foo(*bar)。 -
@Xeo:至少在 MSVC 2010 中,传递派生指针(即
foo(bar))不起作用。 -
“显然行不通”是什么意思?代码编译并正确运行;你是在问如何避免创建一个临时的
shared_ptr来传递给函数?我很确定没有办法避免这种情况。 -
@Seth:我不同意。我认为有理由通过值传递共享指针,并且几乎没有理由通过引用传递共享指针(所有这些都没有提倡不需要的副本)。在这里推理stackoverflow.com/questions/10826541/…
标签: c++ casting c++11 shared-ptr smart-pointers