从析构函数中传出共享指针

时间:2013-02-27 11:09:57

标签: c++ this destructor shared-ptr

我有一个对象BagOfThings,它存储了一组Thing和一个BagOfThingsListener的列表,它们想知道添加Thing的时间或者从已加入的BagOfThings中移除。像这样:

class Thing;
class BagOfThings;

class BagOfThingsListener {
public:
  virtual ~BagOfThingsListener() {}
  virtual void thingAdded(std::shared_ptr<BagOfThings> bag, std::shared_ptr<Thing> thing)=0;
  virtual void thingRemoved(std::shared_ptr<BagOfThings> bag, std::shared_ptr<Thing> thing)=0;
};

class BagOfThings: public enable_shared_from_this<BagOfThings> {
private:
  std::set<std::shared_ptr<Thing>> things;
  std::list<std::shared_ptr<BagOfThingsListener>> listeners;

private:
  BagOfThings() {}

public:
  static std::shared_ptr<BagOfThings> create() {
    return std::shared_ptr<BagOfThings>(new BagOfThings());
  }

  void addThing(std::shared_ptr<Thing> thing) {
    things.insert(thing);
    for (auto it=begin(listeners); it!=end(listeners); ++it) {
      (*it)->thingAdded(shared_from_this(), thing);
    }
  }

  void removeThing(std::shared_ptr<Thing> thing) {
    things.erase(thing);
    for (auto it=begin(listeners); it!=end(listeners); ++it) {
      (*it)->thingRemoved(shared_from_this(), thing);
    }
  }

  ~BagOfThings() {
    for (auto it=begin(things); it!=end(things);) {
      auto currentIt=it++;
      auto &currentThing=*currentIt;
      things.erase(currentIt);
      for (auto it2=begin(listeners); it2!=end(listeners); ++it2) {
        (*it2)->thingRemoved(shared_from_this(), currentThing);
      }
    }
  }
};

除了析构函数之外,这个工作正常,因为当所有shared_from_this()都被销毁时,你不允许使用shared_ptr,因为它们在调用析构函数时就已经被破坏了。在这种情况下,我正在使用共享指针,但在我看来,从析构函数中分配这个指针仍然是有问题的 - 例如,有人可能存储指针。但是在这种情况下(希望让听众知道删除所有元素的破坏),我无法看到一个明显的好方法,而不从监听器中删除指向调用者的指针(即thingAdded会成为void thingAdded(std::shared_ptr<Thing>))。

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

为什么BagOfThingsListener :: thingAdded和BagOfThingsListener :: thingRemoved需要采用shared_ptr?对BagOfThings的引用/ const引用是否足够?当BagOfThings调用thingAdded或thingRemoved时,你知道this指针是有效的,因此引用也是有效的。