1

コンストラクターがメンバー変数を初期化する前に、無料のGlobalInitializer()を呼び出す必要があるとします。例えば:

class Foo {
  public:
    Foo() : bar_()
    {
      // calling GlobalInitializer() here is too late
    }
  Bar bar_;
};

FooでGlobalInitializer()を呼び出すのは遅すぎます。これは、bar_が初期化される前に呼び出す必要があるためです。これに対する私のハッキーな回避策は、スーパークラスを作成することでした:

class MyInitializer {
  protected:
    MyInitializer() {
      GlobalInitializer();
    }
};
class UglyFoo : public MyInitializer
{
  public:
    UglyFoo() : bar_()
    { }
  Bar bar_;
};

UglyFooは仕事を成し遂げますが、この醜いMyInitializerクラスが必要です。同じ結果を達成する、よりクリーンなデザインパターンまたはリファクタリングはありますか?

追記:GlobalInitializer()は、ユーザーがFoo()をインスタンス化しない限り、避けたい高価な呼び出しです。GlobalInitializer()内には、複数の呼び出しに対するガードがあります。また、GlobalInitializer()を呼び出す必要がある他のクラス(FooBarなど)もありますが、1つのプロセスでは、GlobalInitializer()は実際には1回(FooまたはFooBarがインスタンス化されている場合)または1回も機能しません( FooまたはFooBarのインスタンス化)。

4

5 に答える 5

4
class Foo {
private:
    struct Initializer {
        Initializer() { GlobalInitializer(); }
    };
    Initializer initializer__;  // declare before bar__ to ensure it is constructed first

public:
    Foo() : bar_()
    {
    }

    Bar bar_;
};
于 2011-10-20T11:25:50.470 に答える
1

おそらく、設計を再考する必要があります。

良い設計とは、疎結合を意味します。オブジェクトの作成が別のメソッド呼び出しに依存している場合、深刻な問題があります。

これが必要な場合は、おそらくGlobalInitializerのコンストラクター内で呼び出す必要がありますが、これを行うbar_最善の方法は、設計を再考することです。

于 2011-10-20T11:26:42.880 に答える
0

クラスがそれらの外部に不当に依存しているため、あなたがしていることはオブジェクト指向の値に違反しているようです。代わりに、クラスを再設計してそれを回避することをお勧めします。

そうは言っても、各クラスを別のクラスに継承させずに設計モデルに適合するオプションは、MyInitializer クラスをシングルトン オブジェクトとして作成し、この初期化に依存する各クラスに MyInitializer を追加することです。シングルトンは、最初にインスタンス化されたときにのみ初期化を実行します。

于 2011-10-20T11:24:04.660 に答える
0

夢の中で私に出くわしました: bar_ をポインターに変更します:

class Foo {
  public:
    Foo()
    {
      GlobalInitializer();
      // now we can call GlobalInitializer() in time
      bar_ = new Bar; 
    }
    ~Foo()
    {
      delete bar_;
    }

  private:
    Bar* bar_;
};
于 2011-11-17T20:33:05.453 に答える
0

おそらく、初期化するものをリファクタリングしてGlobalInitializer、もはやグローバルにならないようにすることができます。次に、クラスにそのデータを与える方法についてのオプションが開きます。ご存知のように、グローバルはすべて悪いものです。

于 2011-10-20T11:25:44.580 に答える