Mat*_*ine 74 c++ casting smart-pointers shared-ptr c++11
将shared_ptr派生类型传递给采用shared_ptr基类型的函数的最佳方法是什么?
我通常通过shared_ptr引用传递s以避免不必要的副本:
int foo(const shared_ptr<bar>& ptr);
Run Code Online (Sandbox Code Playgroud)
但如果我尝试做类似的事情,这不起作用
int foo(const shared_ptr<Base>& ptr);
...
shared_ptr<Derived> bar = make_shared<Derived>();
foo(bar);
Run Code Online (Sandbox Code Playgroud)
我可以用
foo(dynamic_pointer_cast<Base, Derived>(bar));
Run Code Online (Sandbox Code Playgroud)
但这似乎是次优的,原因有两个:
dynamic_cast对于简单的派生到基础演员来说,A 似乎有点过分.dynamic_pointer_cast创建一个指向传递给函数的副本(虽然是临时的).有更好的解决方案吗?
原来这是一个缺少头文件的问题.此外,我在这里尝试做的是一个反模式.通常,
不影响对象生命周期的函数(即对象在函数持续时间内保持有效)应采用普通引用或指针,例如int foo(bar& b).
使用对象的函数(即,是给定对象的最终用户)应该采用unique_ptrby值,例如int foo(unique_ptr<bar> b).std::move调用者应该将值放入函数中.
延长对象生命周期的函数应采用shared_ptrby值,例如int foo(shared_ptr<bar> b).避免循环引用的通常建议适用.
有关详细信息,请参阅Herb Sutter的回归基础讲座.
Bre*_*hns 37
虽然Base与Derived是协变的和原始指针他们会采取相应的行动,shared_ptr<Base>并且shared_ptr<Derived>是不是协变的.这dynamic_pointer_cast是处理此问题的正确和最简单的方法.
(编辑: static_pointer_cast更合适,因为你从派生到基础,这是安全的,不需要运行时检查.请参阅下面的评论.)
但是,如果您的foo()函数不希望参与延长生命周期(或者更确切地说,参与对象的共享所有权),那么最好在接受时将其接受const Base&并取消引用.shared_ptrfoo()
void foo(const Base& base);
[...]
shared_ptr<Derived> spDerived = getDerived();
foo(*spDerived);
Run Code Online (Sandbox Code Playgroud)
顺便说一句,因为shared_ptr类型不能协变,所以返回协变返回类型的隐式转换规则在返回类型时不适用shared_ptr<T>.
Pet*_*ker 10
听起来你太努力了.shared_ptr复制便宜; 这是它的目标之一.通过引用传递它们并没有真正实现.如果您不想共享,请传递原始指针.
也就是说,有两种方法可以做到这一点,我可以想到我的头脑:
foo(shared_ptr<Base>(bar));
foo(static_pointer_cast<Base>(bar));
Run Code Online (Sandbox Code Playgroud)
如果您忘记在派生类上指定公共继承,也会发生这种情况,即,如果像我一样,您可以这样编写:
class Derived : Base
{
};
Run Code Online (Sandbox Code Playgroud)
还要检查#include源文件中是否包含包含派生类的完整声明的头文件。
我有这个问题。该std::shared<derived>不会投给std::shared<base>。我已经预先声明了两个类,以便可以保存指向它们的指针,但是由于我没有#include编译器,因此无法看到一个类是从另一个类派生的。