[解決済み] C++規格で認められているメンバ変数と同じ名前をコンストラクタの引数に使ってメンバ変数を初期化すること?重複
質問
以下の例のように、同名のコンストラクタ引数でメンバ変数を初期化することが可能であることがわかりました。
#include <cstdio>
#include <vector>
class Blah {
std::vector<int> vec;
public:
Blah(std::vector<int> vec): vec(vec)
{}
void printVec() {
for(unsigned int i=0; i<vec.size(); i++)
printf("%i ", vec.at(i));
printf("\n");
}
};
int main() {
std::vector<int> myVector(3);
myVector.at(0) = 1;
myVector.at(1) = 2;
myVector.at(2) = 3;
Blah blah(myVector);
blah.printVec();
return 0;
}
g++ 4.4 を引数として
-Wall -Wextra -pedantic
は警告を出さず、正しく動作します。clang++でも動きます。C++の標準ではどうなっているのでしょうか?これは合法で、常に動作することが保証されているのでしょうか?
どのように解決するのですか?
<ブロッククオートC++の標準ではどうなっているんだろう?合法で、常に動作することが保証されているのでしょうか?
はい、それは完全に合法です。完全に標準に適合しています。
Blah(std::vector<int> vec): vec(vec){}
^ ^
| |
| this is the argument to the constructor
this is your member data
規格の参照を求められたので、ここに例とともに掲載します。
§12.6.2/7
mem-initializerの式リスト内の名前は、mem-initializerが指定されたコンストラクタのスコープで評価されます。
[Example:
class X {
int a;
int b;
int i;
int j;
public:
const int& r;
X(int i): r(a), b(i), i(i), j(this->i) {}
//^^^^ note this (added by Nawaz)
};
<ブロッククオート
はX::aを参照するようにX::rを初期化します。 X::bをコンストラクタのパラメータiの値で初期化します. を初期化し、X::bをコンストラクタ・パラメータiの値で初期化します。 X::i をコンストラクタのパラメータ i の値で初期化し、X::j をコンストラクタのパラメータ i の値で初期化します。 を初期化し、X::j を X::i の値で初期化する。 をX::iの値で初期化します。 これはクラスXのオブジェクトが生成されるたびに行われます。 これはクラスXのオブジェクトが生成されるたびに行われます。]
[注意: なぜなら mem-initializerはコンストラクタのスコープで評価されるため のスコープで評価されるので、この ポインタを使用することができます。 の式リストで使用することができます。 の式リストで、初期化されるオブジェクトを参照するために 初期化されるオブジェクトを参照することができます。]
ご覧の通り、上記の例やStandard自体の解説には、他にも興味深い点があります。
ところで、余談ですが、なぜパラメータを const として受け取ってはどうでしょうか。
Blah(const std::vector<int> & vec): vec(vec) {}
^^^^const ^reference
元のベクトルオブジェクトの不必要なコピーを避けることができます。
関連
-
[解決済み】C++でint型に無限大を設定する
-
[解決済み】LLVMで暗黙のうちに削除されたコピーコンストラクタの呼び出し
-
[解決済み】C++のGetlineの問題(オーバーロードされた関数 "getline "のインスタンスがない
-
[解決済み】浮動小数点例外エラーが発生する: 8
-
[解決済み】クラステンプレートの使用にはテンプレート引数リストが必要です
-
[解決済み】システムが指定されたファイルを見つけられませんでした。
-
[解決済み] 配列のベクトルを扱う正しい方法
-
[解決済み】変数やフィールドがvoid宣言されている
-
[解決済み] 構造体のsizeofは、なぜ各メンバーのsizeofの合計と等しくないのですか?
-
[解決済み] ベースクラスのコンストラクタを呼び出す際のルールは?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】クラステンプレートの引数リストがない
-
[解決済み】抽象クラス型の無効なnew-expression
-
[解決済み】IntelliSense:オブジェクトに、メンバー関数と互換性のない型修飾子がある
-
[解決済み】c++でstd::vectorを返すための効率的な方法
-
[解決済み】リンカーエラーです。"リンカ入力ファイルはリンクが行われていないため未使用"、そのファイル内の関数への未定義参照
-
[解決済み] gdbを使用してもデバッグシンボルが見つからない
-
[解決済み] 数値定数の前にunqualified-idを付けて、数値を定義することを期待する。
-
[解決済み】Visual Studioのデバッガーエラー。プログラムを開始できません 指定されたファイルが見つかりません
-
[解決済み】警告 - 符号付き整数式と符号なし整数式の比較
-
[解決済み】'std::cout'への未定義の参照