13

今日、初期化でクラス変数を初期化する同僚のコードに気付きました。しかし、それは警告を引き起こしていた、と彼は言います。変数の初期化は、中括弧内ではなく、現在の場所で行う方が良いのはなぜですか?

DiagramScene::DiagramScene( int slideNo, QRectF screenRect, MainWindow* parent )
    : QGraphicsScene( screenRect, parent ),
    myParent( parent ), 
    slideUndoImageCurrentIndex(-1),
    nextGroupID(0),
    m_undoInProgress(false),
    m_deleteItemOnNextUndo(0)
    line(0),
    path(0)
{
    /* Setup default brush for background */
    scDetail->bgBrush.setStyle(Qt::SolidPattern);
    scDetail->bgBrush.setColor(Qt::white);
    setBackgroundBrush(scDetail->bgBrush);

}
4

8 に答える 8

26
  • (一般的に)より効率的です。クラスのすべてのメンバーは、明示的に初期化するかどうかにかかわらず、コンストラクターで初期化されます。初期化子を指定しない場合、メンバーのデフォルトのコンストラクターが実行されます。コンストラクタ本体で値を代入すると、代入演算子が再度呼び出されます。スカラー値にはコンストラクターがないため、これはスカラー値には適用されません。
  • イニシャライザ リストで誤って値を 2 回割り当てることはできません。
  • コンパイラは、初期化子を記述する順序が、クラスでメンバーが定義されている順序と一致することを確認できます。C++ 標準では、初期化子を記述した順序に関係なく、宣言された順序でメンバーを初期化する必要があります。コンパイラーにこの順序をチェックさせることで、プログラマーはイニシャライザーが実行される順序を確実に知ることができます (繰り返しますが、これはスカラーよりも非 POD メンバーにとってより重要です)。
  • 参照型とconstメンバーは、参照またはメンバーに割り当てることができないため、初期化子リストで初期化する必要がありますconst
于 2008-10-02T10:34:12.137 に答える
4

メンバーは一度だけ初期化されるため、初期化リストのメンバーの初期化を行うことをお勧めします。メンバー自体がクラスである場合、これはパフォーマンス(さらには動作)に大きな違いをもたらす可能性があります。メンバーがすべて非定数、非参照の基本データ型である場合、通常、その違いはごくわずかです。

:基本的なデータ型には初期化リストが必要な場合があります。特に、型が定数または参照の場合です。これらのタイプの場合、データは1回しか初期化できないため、コンストラクターの本体で初期化することはできません。詳細については、この記事を参照してください。

メンバーの初期化順序は、メンバーが初期化リストで宣言されている順序ではなく、クラス定義で宣言されている順序であることに注意してください。初期化リストの順序を変更することで警告を修正できる場合は、そうすることを強くお勧めします。

私の推奨事項は次のとおりです。

  • あなたは初期化リストが好きになることを学びます。
  • 同僚は、メンバーの初期化順序の規則を理解しています(そして警告を避けます)。
于 2008-10-02T10:42:34.237 に答える
3

Greg Hewgillの優れた答えに加えて、初期化リストでconst変数を設定する必要があります。

于 2008-10-02T10:48:41.120 に答える
2

コンストラクターの本体 (「中括弧内」) では、メンバー変数が既にデフォルトで構築されているためです。自明でない構造を持つ型のメンバー変数がある場合、最初にそれをデフォルトで構築し、次にコンストラクターで他の値を割り当てた場合、カスタム構築を行うことができる場合、パフォーマンスに影響を与える可能性があります。それを直接。

また、一部の型はデフォルトで構築されない場合があり (参照など)、初期化リストで構築する必要があります。

于 2008-10-02T10:37:02.317 に答える
2

const 変数がある場合、それらの値は代入によって設定できません。

代入のように一時オブジェクトが作成されないため、初期化はオブジェクト (組み込みまたは組み込みではない) に値を代入する場合にも少し効率的です。

詳細については、 C++ FAQ-Liteを参照してください。

于 2008-10-02T10:41:45.113 に答える
0

http://web.tiscali.it/fanelia/cpp-faq-en/ctors.html#faq-10.6で集められた知恵を見てみましょう。

于 2008-10-02T10:40:49.437 に答える
0

Greg Hegwell の回答にはいくつかの優れたアドバイスが含まれていますが、コンパイラが警告を生成する理由は説明されていません。

コンストラクターの初期化子リストがコンパイラーによって処理されるとき、アイテムは、初期化子リストに表示される順序ではなく、クラス宣言で宣言された順序で初期化されます。

一部のコンパイラは、初期化子リストの順序が宣言の順序と異なる場合に警告を生成します (そのため、アイテムがリストの順序で初期化されていなくても驚くことはありません)。クラス宣言を含めていませんが、これが表示されている警告の原因である可能性があります。

この動作の理論的根拠は、クラスのメンバーは常に同じ順序で初期化する必要があるためです。クラスに複数のコンストラクターがある場合でも (初期化子リストでメンバーの順序が異なる場合があります)。

于 2010-05-06T16:39:59.160 に答える
0

Greg の回答へのもう 1 つの追加: デフォルトのコンストラクターを持たない型のメンバーは、初期化リストで初期化する必要があります。

于 2008-10-02T16:14:32.647 に答える