由于使用共享指针,我经常在我想将它们传递给不需要(必须)拥有该对象的函数的情况下运行。因为我知道在函数调用期间对象是有效的,所以我有四个传递指针的选项:
起初我开始经常使用弱指针(因为我已经有了它们),但是一直锁定它们的开销很烦人并且达到了性能。现在我考虑通过引用传递原始指针或共享指针。有最好的做法吗?
答案 0 :(得分:6)
我建议通过const std::shared_ptr<T>&
传递它们。这有两个好处:
在他们可能(或可能不)是线程切换的情况下,我经常使用它。例如:
struct Foo { void bar() {} };
class BaseImpl
{
public:
void CallBar(const std::shared_ptr<Foo>& f);
{
do_call_bar(f);
}
private:
virtual void do_call_bar(const std::shared_ptr<Foo>& f) = 0;
};
class DerivedDirectCall : public BaseImpl
{
virtual void do_call_bar(const std::shared_ptr<Foo>& f) override
{
f->bar();
}
};
class DerivedAsyncCall : public BaseImpl
{
virtual void do_call_bar(const std::shared_ptr<Foo>& f) override
{
// assume invoke passes this off
// to be done asynchronously
invoke([f] () { f->bar(); });
}
};
根据实现是DerivedDirectCall
还是DerivedAsyncCall
,只有在必要时才会复制共享指针。
此外,上面的评论与this article on smart pointers相关联。我想明确一点,我的答案是关于传递智能指针本身。如果您知道生命周期不一定会被扩展,那么最好通过引用(或原始指针传递指向对象,但只允许nullptr
参数)。
答案 1 :(得分:4)
由于使用共享指针,我经常在我想将它们传递给不需要(必须)拥有该对象的函数的情况下运行。
你的措辞听起来像你的实际所关心的函数是指向的对象,而不是指针。因此,您应该传递对象(通过引用):
void my_func(int &x);
int main()
{
shared_ptr<int> demo_ptr = make_shared<int>(5);
my_func(*demo_ptr);
}
答案 2 :(得分:3)
堆栈保证了生命周期。如果您要传递weak_ptr
,那么该函数无论如何都必须获得shared_ptr
。
您希望按值传递原始指针,或者通过引用传递实际对象。
这两个选项之间的选择取决于您调用的函数的语义。如果nullptr
是函数的有效参数,则传递原始指针。否则,通过引用传递对象。