9

クラスXがあるとします:

struct X
{
   ...
};

そして、グローバル ベクトル V があります。

vector<X*> V;

X の新しいインスタンスを V に追加したいのは、それが動的に割り当てられている場合に限ります (サブオブジェクトではなく、完全な最も派生したオブジェクトとして)。

int main()
{
    X x; // not added to V
    new X; // added to V

    struct D : X {};
    new D; // not added to V
}

これを行う方法はありますか?おそらくoperator new何らかの形でオーバーロード/オーバーライドすることによってですか?

4

3 に答える 3

8
struct X {
public:
    static void* operator new(std::size_t size) {
        void* p = ::operator new(size);
        if (size == sizeof(X))
            V.push_back(static_cast<X*>(p));
    }
    static void operator delete(void* p, std::size_t size) {
        if (size == sizeof(X))
            V.erase(std::remove(V.begin(), V.end(), p), V.end());
        ::operator delete(p, size);
    }
};

の要素がVまだ実際には ではない、またはもはやX. ユーザーがこれらの機能を回避することは可能ですが、試してみる必要があります。

を継承するXが同じサイズの別のクラスがある場合 (したがって、おそらく「空の」基本クラスを除いて他のサブオブジェクトはありません)、struct Y : public X {};上記のコードnew YX. これが問題になる場合は、そのようなすべてのクラスにoperator newandも追加する必要があります。もっと一般的な解決策はないと思います。operator voidY

于 2013-05-29T14:13:47.793 に答える
1

あなたが望むものの最良の近似は、動的に割り当てられたオブジェクトにファクトリの使用を強制することだと思います:

#include <algorithm>
#include <utility>
#include <vector>

class X {
  static std::vector<X*> dynamic_xs;

  static void* operator new(std::size_t size) {
    return ::operator new(size);
  }

public:
  ~X() {
    auto end = std::end(dynamic_xs);
    auto pos = std::find(std::begin(dynamic_xs), end, this);
    if (pos != end) {
      if (pos != --end) {
        std::iter_swap(pos, end - 1);
      }
      dynamic_xs.pop_back();
    }
  }

  template <typename... Args>
  friend X* make_x(Args&&... args) {
    X* p = new X(std::forward<Args>(args)...);
    dynamic_xs.push_back(p);
    return p;
  }
};

std::vector<X*> X::dynamic_xs;

クライアントは stack-allocated をインスタンス化できますが、 is でXあるため、動的割り当てによりアクセス エラーが発生します。operator newprivate

于 2013-05-29T14:42:43.057 に答える