将共享指针传递给非拥有函数时的最佳做法是什么?

Mar*_* R. 3 c++ pointers

由于使用共享指针,我经常在我想将它们传递给不必(必须)拥有该对象的函数的情况下运行.因为我知道在函数调用期间对象是有效的,我有四个传递指针的选项:

  1. 按价值
  2. 引用
  3. 弱指针
  4. 原始指针

起初我开始经常使用弱指针(因为我已经有了它们),但是一直锁定它们的开销很烦人并且达到了性能.现在我考虑通过引用传递原始指针或共享指针.有最好的做法吗?

Cha*_*had 6

我建议通过它们const std::shared_ptr<T>&.这有两个好处:

  1. 引用计数不会产生任何开销(默认情况下不会增加引用计数)
  2. 如有必要,该函数可以自由获取共享指针的副本

在可能(或可能不是)线程切换的情况下,我经常使用它.例如:

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(); });
   }
};
Run Code Online (Sandbox Code Playgroud)

取决于实现是否DerivedDirectCallDerivedAsyncCall仅在必要时复制共享指针.

此外,上面的评论链接了这篇关于智能指针的文章.我想明确一点,我的答案是关于传递智能指针本身.如果您知道生命周期不一定会被扩展,那么最好通过引用(或原始指针)传递指向的对象,但只需要允许nullptr参数.