1
 class a
 {
 public:
 a() : b(5), a1(10) //will firstly initialize a1 then b, so order here doesn't matter
 int a1;
 private:
 int b;
 }

問題は、順序を変更する方法です(a1の前にbを初期化する)?解決策が私にとってうまくいかないように、私はプライベートよりもパブリックメンバーを持っている必要があります。もちろん、ここではintを使用しています。問題はもっと複雑ですが、これは私の問題が何であるかを示す単なる例です。

4

4 に答える 4

5

初期化の順序を変更することはできません。これは、クラス内のメンバーの宣言の順序によって常に定義されます。これが必要なのは、破棄の順序が構築の順序のである必要があるためです。構築の順序を変更した場合、コンパイラーは、適切な破棄を生成するために、メンバーを初期化した順序を追跡する必要があります。シーケンス。

だから私のアドバイスは:

  1. ただそれと一緒に暮らす、そして;
  2. メンバー変数の作成順序に依存しないでください。

ポイント2)を達成するために、メンバーにデフォルトの初期化を行うデフォルトのコンストラクターを提供し、コンストラクターの本体内で必要な順序でメンバーを適切に初期化できます(つまり、構造を論理初期化から切り離します)。

于 2013-01-28T14:42:01.673 に答える
3

初期化の順序は、メンバー変数の宣言の順序によって決定されます。したがって、b前に初期化するa場合は、前に宣言する必要があります。

class a
{
  public:
   a() : b(5), a1(10) {}
  private:
   int b;
  public:
   int a1;
};
于 2013-01-28T14:41:11.687 に答える
2

私があなたが正しいと理解しているなら、あなたはある種のスタイルガイドを持っていて、パブリックメンバーはプライベートの前にあるべきだと言っています。

その場合は、すべてのメンバー変数をプライベートとして宣言し、代わりにそれらへのアクセサー関数を作成することをお勧めします。そうすればあなたはそれを回避します。

class a
 {
 public:
   a() : _a1(5), _b(10) 
   int a1() const { return _a1; }
   void a1(int value) { _a1 = value; }
   int b() const { return _b; }
   void b(int value) { _b = value; }

 private:
   int _a1;
   int _b;
 }

どんな正気のコンパイラもとにかくそれを最適化するので、オーバーヘッドは最小限になります。

于 2013-01-28T14:52:47.123 に答える
1

オブジェクトをbプライベートにし、前に宣言しa1、のコンテンツにアクセスするためのアクセサ関数を作成しますb。[必要に応じて、bオブジェクトへの参照を返すようにします。これにより、呼び出し元のコードがオブジェクトを変更できるようになります。ただし、パブリック宣言を使用する場合でも、を返す場合でも、クラスの内部を呼び出し元のコードに公開するのは明らかに悪い設計です。参照]

于 2013-01-28T14:50:30.743 に答える