0

s のセットとs のリストをBagOfThings格納するオブジェクト があります。これらは、が追加されたとき、または追加された から削除されたときを知りたいと考えています。このような:ThingBagOfThingsListenerThingBagOfThings

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の s が破棄されたときに使用できないため、無効なデストラクタを除いて正常に機能します。この場合、私は共有ポインタを使用していますが、デストラクタから this ポインタを配布することはとにかく問題があるように思えます。たとえば、誰かがポインタを保存する可能性があります。thingAddedしかし、この場合(すべての要素の削除の破棄をリスナーに知らせたい)、呼び出し元へのポインターをリスナーから削除しないと(つまり、 になる) 、明らかに良い方法がわかりませんvoid thingAdded(std::shared_ptr<Thing>)

何か案は?

4

1 に答える 1

0

BagOfThingsListener::thingAdded と BagOfThingsListener::thingRemoved が shared_ptr を取る必要があるのはなぜですか? BagOfThings への参照/定数参照で十分ではないでしょうか? BagOfThings が thingAdded または thingRemoved を呼び出すと、this ポインターが有効であることがわかっているため、参照も有効になります。

于 2013-02-27T12:04:46.243 に答える