1

私はそのような構造体を書きました... C++ 11で

struct StackOverflow
{
    int x;
    StackOverflow(){}
    StackOverflow(int x) { x = x; }
};

後者のコンストラクターを次のように書くべきだったことはわかっていますがStackOverflow(int x) : x(x) {}、何かを学んだので、この場合はそうしなかったことをうれしく思います。

C++11 コンパイラは、ステートメントで正しい処理{x = x;}を行いませんでした。実際、構造体メンバーxは初期化さえされませんでした (アプリケーションが失敗した理由をデバッグしているときに、ランダムな値がありました)。また、コンパイラの警告は表示されませんでした。

これはうまくいくはずではありませんか?

4

3 に答える 3

4

すでに知っているように見えるコンストラクター初期化リストを使用する必要があります。したがって、コードが意図したとおりに実行されない理由を知りたいだけだと思います。問題は、プログラムで表現されていないため、コンパイラが意図を認識していないことです。次のようにプログラムで意図を表現する必要があります。

StackOverflow(int x) { this->x = x; }

コンパイラは、どれがどれであるかを知る必要xがありxます。を使用するthis->xと、コンパイラはユーザーの意図を認識します。

于 2012-12-29T18:03:00.227 に答える
3

コンストラクタ初期化リストで初期化される場合を除いて、パラメータはデータメンバーをシャドウイングします。

はデータメンバーをシャドウイングしx = xxいるため、パラメータをそれ自体に割り当てています。

StackOverflow(int x) : x(x) {}
//                     ^ ^
//                     | +-- parameter x
//                     |
//                     +---- data member x

StackOverflow(int x) { x = x; }
//                     ^   ^
//                     |   |
//                     +---+-- parameter x
于 2012-12-29T18:06:39.937 に答える
2

xいいえ、メンバーを非表示にするコンストラクターの名前空間で名前が付けられた新しい変数を導入しました。

コンパイラから警告が表示される場合がありますが、必須ではありません

次の 3 つのオプションがあります。

  • パラメータの名前を変更します
  • 初期化リストを使用する
  • メンバーに資格を与えるthis->x

最初のものを使用してください。これが最もエレガントです。この単純なケースでは、大きな違いはありxませんが、クラス メンバーを参照しないことと、クラス メンバーthis->xを使用するときに記述する必要があることを覚えておく必要がある、より大きなコンストラクターについて考えてみてください。

于 2012-12-29T18:04:02.137 に答える