什么是去传递一个最好的方法shared_ptr
派生类型的给带有一个功能shared_ptr
基本类型的?
我一般通过shared_ptr
S按参考,以避免不必要的副本:
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)
通常的建议,以避免循环引用适用。
见香草萨特的歌姬交谈了解详情。
虽然Base
和Derived
是协变和原始指针到他们将相应地动作, shared_ptr<Base>
和shared_ptr<Derived>
不是协变。 该dynamic_pointer_cast
是处理这个问题的正确和最简单的方法。
( 编辑: static_pointer_cast
因为你来源于基地,这是安全的,不需要运行时检查铸件会更合适,请参阅下面的评论。)
但是,如果您foo()
函数不希望参加延长寿命(或者说,参加对象的共享所有权的一部分),那么它的最好接受const Base&
和取消引用shared_ptr
传递时,到foo()
void foo(const Base& base);
[...]
shared_ptr<Derived> spDerived = getDerived();
foo(*spDerived);
顺便说一句,因为shared_ptr
类型不能协变,横跨协变返回类型的隐式转换的规则不返回类型时,适用shared_ptr<T>
听起来像是你想太硬。 shared_ptr
是廉价的复制; 这就是目标之一。 参照各地传递他们并没有真正大有作为。 如果你不想做的共享,通过原始指针。
这就是说,有两种方法可以做到这一点,我能想到的把我的头顶部:
foo(shared_ptr<Base>(bar));
foo(static_pointer_cast<Base>(bar));
此外,检查#include
包含派生类的完整声明的头文件是在源文件中。
我有这个问题。 所述std::shared<derived>
不会投射到std::shared<base>
。 我前宣布这两个类,这样我可以抱球给他们,而是因为我没有足够的#include
编译器无法看到,一类是从其他的。
这也将发生,如果你忘了在派生类中指定公有继承,如果你像我写这篇文章,即:
class Derived : Base
{
};