将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
对于简单的派生到基础演员来说,A 似乎有点过分。dynamic_pointer_cast
创建一个指向传递给函数的副本(虽然是临时的)。有更好的解决方案吗?
原来这是一个缺少头文件的问题。此外,我在这里尝试做的是一个反模式。通常,
int foo(bar& b)
。unique_ptr
by值,例如int foo(unique_ptr<bar> b)
。std::move
调用者应该将值放入函数中。shared_ptr
by值,例如int foo(shared_ptr<bar> b)
。通常的建议是避免循环引用。发布于 2019-01-03 13:34:19
shared_ptr
复制很简单; 这是它的目标之一。通过引用传递它们并没有真正实现。如果您不想共享,请传递原始指针。
也就是说,有两种方法可以做到这一点,我可以想到的:
foo(shared_ptr<Base>(bar));
foo(static_pointer_cast<Base>(bar));
发布于 2019-01-03 15:04:10
虽然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);
顺便说一下,因为shared_ptr
类型不能协变,所以返回协变返回类型的隐式转换规则在返回类型时不适用shared_ptr<T>
。
https://stackoverflow.com/questions/-100006347
复制相似问题