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

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

Stack Overflow用户
提问于 2019-01-03 05:17:00
回答 2查看 0关注 0票数 0

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

我通常通过shared_ptr引用传递s以避免不必要的副本:

代码语言: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对于简单的派生到基础演员来说,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)。通常的建议是避免循环引用
EN

回答 2

Stack Overflow用户

发布于 2019-01-03 13:34:19

shared_ptr复制很简单; 这是它的目标之一。通过引用传递它们并没有真正实现。如果您不想共享,请传递原始指针。

也就是说,有两种方法可以做到这一点,我可以想到的:

代码语言:javascript
复制
foo(shared_ptr<Base>(bar));
foo(static_pointer_cast<Base>(bar));
票数 0
EN

Stack Overflow用户

发布于 2019-01-03 15:04:10

虽然BaseDerived是协变的和原始指针他们会采取相应的行动,shared_ptr<Base>并且shared_ptr<Derived>不是协变的。这dynamic_pointer_cast是处理此问题的正确和最简单的方法。

编辑: static_pointer_cast更合适,因为你从派生到基础,这是安全的,不需要运行时检查。请参阅下面的评论。)

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

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

顺便说一下,因为shared_ptr类型不能协变,所以返回协变返回类型的隐式转换规则在返回类型时不适用shared_ptr<T>

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

https://stackoverflow.com/questions/-100006347

复制
相关文章

相似问题

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