首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将shared_ptr<Derived>传递为shared_ptr<Base>

将shared_ptr<Derived>传递为shared_ptr<Base>
EN

Stack Overflow用户
提问于 2012-11-15 18:04:46
回答 4查看 85K关注 0票数 131

将派生类型的shared_ptr传递给接受基类型shared_ptr的函数的最佳方法是什么?

我通常通过引用shared_ptr来避免不必要的副本:

代码语言:javascript
复制
int foo(const shared_ptr<bar>& ptr);

但如果我试着做这样的事情,这是行不通的

代码语言:javascript
复制
int foo(const shared_ptr<Base>& ptr);

...

shared_ptr<Derived> bar = make_shared<Derived>();
foo(bar);

我可以用

代码语言:javascript
复制
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的回到基本话题

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-11-15 18:14:31

虽然BaseDerived是协变的,指向它们的原始指针也会相应地起作用,但是shared_ptr<Base>shared_ptr<Derived>而不是协变量。dynamic_pointer_cast是处理此问题的正确和最简单的方法。

(编辑: static_pointer_cast将更合适,因为您将从派生转换为基,这是安全的,不需要运行时检查。见下文的评论。)

但是,如果您的foo()函数不希望参与延长生存期(或者更确切地说,参与对象的共享所有权),那么最好在将const Base&传递给foo()时接受并取消对shared_ptr的引用。

代码语言:javascript
复制
void foo(const Base& base);
[...]
shared_ptr<Derived> spDerived = getDerived();
foo(*spDerived);

另外,由于shared_ptr类型不能是协变量的,因此在返回shared_ptr<T>类型时不适用跨协变量返回类型的隐式转换规则。

票数 56
EN

Stack Overflow用户

发布于 2018-07-24 14:08:17

如果您忘记在派生类上指定公共继承,也会发生这种情况,也就是说,如果您像我一样编写以下内容:

代码语言:javascript
复制
class Derived : Base
{
};

而不是:

代码语言:javascript
复制
class Derived : public Base
{
};
票数 71
EN

Stack Overflow用户

发布于 2017-10-19 18:25:16

还要检查包含派生类完整声明的头文件的#include是否在源文件中。

我有这个问题。std::shared<derived>不会转换为std::shared<base>。为了保存指向它们的指针,我转发了声明的两个类,但是由于没有#include,编译器无法看到一个类是从另一个类派生出来的。

票数 18
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13403490

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档