2016-08-15 7 views
1

C++のリファレンス初期化と混同しています。 通常、参照は宣言されたときに初期化されるべきですが、クラスメンバ参照が初期化されずに宣言されていることがわかりました。C++リファレンス初期化

特別な場合ですか?

正しいルールは何ですか。

+8

コードを表示してください。 –

+0

メンバー初期化リストによって初期化されるためです。 – songyuanyao

+1

_ "しかし、クラスメンバ参照が初期化されずに宣言されていることがわかりました。これは特殊なケースですか?" _ Evidence? –

答えて

6

このルールはメンバー変数として参照され、コンストラクタの初期化リストで初期化する必要があります。例:

class X { 
public: 
    X(int& ri) : mri(ri) {} 
    // X() {} // ERROR! no explicit initialization of mri 
    int& mri; 
}; 

int main() { 
    int i; 
    X x(i); 
} 

コンパイルエラーが発生します。標準8.5.3/3(強調鉱山)によると


(私はこの答えは、より便利にするために、コメントから他の良い明確化をまとめることにしました)

初期化子パラメータの宣言(8.3.5)での参照のために省略することができ、 関数の戻り値の型、クラス定義(9.2)内のクラスメンバ宣言の、および extern指定子が明示的に使用されている場所。

したがって、次のコードは、mri変数が宣言されているだけstruct Xの定義のみです。

struct X { 
    int &mri; // declaration of mri (ERROR if you define variable of this struct) 
}; 

タイプXのオブジェクトを作成(定義)すると、コンパイラはエラーを表示しません。あなたが書くとき:

int main() { 
    X x; // error, `x.r` is not bound to any object 
} 

コンパイラは文句を言うでしょう、あなたがxを定義しているので、これがあると、あなたはまた、いくつかのオブジェクトにx.r結合しなければならない場所です。あなたがそれを行うことができる唯一の場所は、コンストラクタの初期化リストです。

また、非静的データメンバとして参照を追加すると、コンパイラはデフォルトのコンストラクタを削除としてマークすることがあります。

+4

ダウン投票は何ですか?この答えは正しい! (私はちょうどほぼ同じ回答BTWを投稿しようとしていた)。 –

+0

暗闇の中に撮影する前にOPで一番明瞭にしましょう。適切な反応は、近い投票です(とコメントかもしれません)。トピック以外の質問はこちらからお願いします。 –

+0

OP-sの混乱は、 'int & mri;'が初期化されていない参照のように見えるという事実からかもしれません。しかし、私はちょうど推測しています。 – marcinj