5

与えられた:

class Foo {

private:
    static int cntFoos;

    //... stuff...

public:
     Foo() { cntFoos++; }
     ~Foo() { cntFoos--; }
};

...ここで、「もの」はプロパティの任意のセットです。(アイデアは、そのクラスのインスタンスのカウンターを持つことです)

それで:

Foo aFoo;
Foo twoFoo=aFoo;

自動コピー コンストラクターが呼び出されるため、これをカウントし損ないます。

自動的に作成された新しいインスタンスを反映するカウンターを維持する方法はありますか? 明示的なコピー コンストラクターを実装すると、すべてのプロパティを 1 つずつ割り当てる必要があります。ただし、メンバーごとの浅いコピーが必要です。ディープ コピーを実行する必要がないため、明示的なコピー コンストラクターを実装するのは多くの不要な作業のように思えます。

4

2 に答える 2

5

ほとんどのメンバーに対してデフォルトの動作が必要で、1 つの (静的) メンバーに対してのみ特別な処理が必要な場合は、その特別な処理を独自のクラスにカプセル化し、そのクラスのメンバー変数を作成してみませんか? このような:

template<typename T>
class InstanceCounter
{
public:
  static int Count;

  // Automatically invoked when a class containing it is created.
  InstanceCounter() { Count++; }

  // Automatically invoked when a class containing it is destroyed.
  ~InstanceCounter() { Count--; }

  // Automatically invoked when a class containing it is copy-constructed.
  InstanceCounter(const InstanceCounter& rhs) { Count++; }

  // No need to override operator=

  // Allow this counter to be used as an int.    
  operator int() const { return Count; }
};

template<typename T>
int InstanceCounter<T>::Count;

class Foo
{
public:
  InstanceCounter<Foo> count;
};

実装上の注意:

  • InstanceCounterさまざまなクラスが独自のインスタンス数を簡単に持つことができるように、テンプレートを作成しました。
  • C++11 の場合は、 の移動コンストラクターと移動代入演算子も提供する必要がありますInstanceCounter

別の方法として、CRTP イディオムを使用することをお勧めします。

template<typename T>
class InstanceCounted
{
public:
  static int InstanceCount;

  // Automatically invoked when a class containing it is created.
  InstanceCounted() { InstanceCount++; }

  // Automatically invoked when a class containing it is destroyed.
  ~InstanceCounted() { InstanceCount--; }

  // Automatically invoked when a class containing it is copy-constructed.
  InstanceCounted(const InstanceCounted& rhs) { InstanceCount++; }

  // No need to override operator=
};

template<typename T>
int InstanceCounted<T>::InstanceCount;

class Foo : public InstanceCounted<Foo>
{
  // insert class contents here
};
// Now we can access Foo::InstanceCount.
于 2014-12-04T20:36:03.343 に答える
5

申し訳ありませんが、手動でオーバーロードしてコピーする必要があります。

本当に、本当に、本当にこれに反対している場合は、静的カウンターとオーバーライドされたコピー コンストラクターを持つ抽象親クラスと、実際のデータ メンバーと暗黙的な浅いコピー コンストラクターを持つ子クラスを作成するハックを使用できます。

カプセル化されたクラスの少しハッキーでないアプローチを取ることもできます。カプセル化されたクラスに浅いコピーする値を格納し、外側のクラスの明示的なコピー コンストラクターを実装するときに、その暗黙的なコピー コンストラクターを使用して内側のクラスの浅いコピーを作成します。

于 2014-12-04T20:29:33.543 に答える