c++ - 要获得引用计数,我是否必须使用 shared_ptr 来混淆我的 API?

标签 c++ api pass-by-reference shared-ptr reference-counting

我最近遇到了以下内存错误,在这里很容易发现,但在更复杂的代码中可能更难检测到:

class Foo : public IFoo {
  const Bar& bar_;
public:
  Foo(const Bar& bar) : bar_(bar) {
  }
  void test() {
    // access bar_ here
  }
};

int baz() {
  IFoo* foo = NULL;
  if(whatever) {
    Bar bar;
    foo = new Foo(bar);
  }
  else {
    // create other foo's
  }
  foo->test(); // segmentation fault
}

错误是 Bar立即超出范围,被销毁,然后在 foo->test() 中使用.一种解决方案是创建 Bar在堆上,使用 Bar* bar = new Bar() .但是,我不喜欢这样做,因为我必须保留 Bar* bar指针在顶层,这样我就可以访问和 delete它在最后,即使Bar是特定于该特定代码块的东西 if(whatever){} .

另一种解决方案是 boost::shared_ptr<Bar> ,但我不能只写这个:

  if(whatever) {
    boost::shared_ptr<Bar> bar(new Bar());
    foo = new Foo(*bar);
  }

shared_ptr也立即超出范围,破坏包含的对象。

简而言之,要解决这个问题,我必须使用shared_ptr到处,在Foo作为成员变量,在 Foo 中的构造函数等。一般来说,为了消除这些问题,我所有的 API 等都必须使用 shared_ptr , 这有点难看。但是,这是正确的做法吗?到目前为止,我有时会用它来创建引用计数对象,但我保持我的 API 干净 shared_ptr .你如何处理这个问题,一旦你使用shared_ptr你必须到处使用它吗?

(此外,如果您使用这些引用计数指针,您必须开始担心您是否真的需要 shared_ptrweak_ptr 等)

而且,我会用什么来代替 Foo(const Bar& bar)Foo(const shared_ptr<const Bar> bar)

当然,另一种选择是在 Bar 中添加引用计数。和其他对象,使用 pimpl和你自己的柜台,但作为一般规则,这太乏味了。

最佳答案

实际上我确实到处都使用shared_ptr……有几种方法可以让它看起来不那么困惑。我使用的一个约定是为每个定义的类使用 typedef:

class AClass {
public:
    typedef boost::shared_ptr<AClass> Ptr;
    typedef boost::weak_ptr<AClass> Ref;
    //...
};

使代码更具可读性:)

至于您的具体问题,请记住您可以通过指针传递 bar —— 不过您必须记住在堆上分配它。

关于c++ - 要获得引用计数,我是否必须使用 shared_ptr 来混淆我的 API?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2192326/

相关文章:

c++ - typedef更改含义

ios - Twitter 请求 token 在 iOS 上无效

C# 参数引用和 .net 垃圾回收

c++ - c++ 使用哪个单元测试框架?

c++ - 静态成员变量初始化时

android - 在 Android 上使用微信 API 发布 friend 圈

xml - 这个 cURL 命令中的 -d 是什么意思?

c++ - 当对象引用作为参数传递时,为什么析构函数在函数作用域结束后调用?

c++ - 作为 `const&`轻量级对象传递

C++ 输入数据到用户定义类型的 vector ?