传递shared_ptr作为<Derived>shared_ptr<Base>
Passing shared_ptr<Derived> as shared_ptr<Base>
将派生类型的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)
。避免循环引用的通常建议适用。
有关详细信息,请参阅Herb Sutter的"回归基础"演讲。
如果您忘记在派生类上指定public继承,也会发生这种情况,例如,如果您像我一样编写以下内容:
class Derived : Base
{
};
代替:
class Derived : public Base
{
};
尽管Base
和Derived
是协变的,并且指向它们的原始指针将相应地起作用,但shared_ptr<Base>
和shared_ptr<Derived>
是而不是协变的。dynamic_pointer_cast
是处理此问题的正确且最简单的方法。
(编辑:static_pointer_cast
更合适,因为您是从派生类型转换为基本类型,这是安全的,不需要运行时检查。请参阅下面的注释。)
但是,如果foo()
函数不希望参与延长生存期(或者更确切地说,参与对象的共享所有权),那么最好接受const Base&
,并在将其传递给foo()
时取消引用shared_ptr
。
void foo(const Base& base);
[...]
shared_ptr<Derived> spDerived = getDerived();
foo(*spDerived);
顺便说一句,因为shared_ptr
类型不能是协变的,所以当返回shared_ptr<T>
的类型时,跨协变返回类型的隐式转换规则不适用。
还要检查包含派生类的完整声明的头文件的#include
是否在源文件中。
我有这个问题。std::shared<derived>
不会转换为std::shared<base>
。我已经向前声明了这两个类,这样我就可以保存指向它们的指针,但因为我没有#include
,编译器看不到一个类是从另一个派生的。
听起来你太努力了。CCD_ 28拷贝成本低;这是它的目标之一。通过引用的方式传递它们并没有真正起到多大作用。如果不希望共享,请传递原始指针。
也就是说,有两种方法可以做到这一点,我可以在脑海中想到:
foo(shared_ptr<Base>(bar));
foo(static_pointer_cast<Base>(bar));
- EASTL矢量<向量<int>>连续的
- 引用 std::shared:ptr 以避免引用计数
- dopen():不以 root 身份运行时"failed to map segment from shared object"
- 无法使用 libtool 将 -shared 参数传递给 g++
- 链接 boost 库时"Error while loading shared libraries"引发的,除了我无法使用 root 访问权限来修复它
- 解决方法:'can not be used when making a shared object; recompile with -fPIC'使用Cmake。使用普通的 g++ 工作
- C - 创建矢量&lt; vector&lt; double&gt;&gt;矩阵具有分配而不是inizializ
- C 字符串比较“祝您好运”&gt;“再见”
- 为什么将此对向量&lt; map&lt; int,int&gt;&gt;中的地图进行更新.失败
- gcc -fPIC vs. -shared
- C :对矢量进行排序&lt; struct&gt;(结构有2个整数)基于结构的整数之一
- C 操作员&gt;&gt;与突变器过载
- 明确的专业化“ CheckIntmap&lt;&gt;”实例化
- 是否需要使用 - &gt;运算符在C 中调用成员函数时
- 什么是模板&lt;&gt;inline bla bla
- 在shared_from_this()中的错误类型(在继承类中)(是否有dyn.type-ware shared Poi
- 编辑C Qlist&lt; object*&gt; gt;QML代码和一些QML警告中的模型
- eigen :: llt&lt;eigen :: matrixxd&gt;具有不完整的类型
- 错误,包括&lt; ctype&gt;在原子上使用C 11
- 错误c++visual studio c2227左侧'->;Init';必须指向类/结构/联合/泛型类型