下のリファレンス内にある C++ における委譲コンストラクタの「この機能が必要になった背景・経緯」でいくつか分からないことがあったので質問しました.
・委譲コンストラクタ cpprefjp - C++日本語リファレンス
委譲コンストラクタがなかった頃、複数のコンストラクタで共通の処理を行うために、コンストラクタの本体(body)で共通処理の関数を呼び出していた。しかしこれは、コンストラクタでの初期化が完了したあとに行われる共通処理であるために、パフォーマンスを阻害していた。パフォーマンスを維持するためには、コンストラクタごとに同じ処理を書く必要があり、コードの肥大化が問題となった。
質問の背景
次の質問のある解答にコメントしていますが,提案もあり改めて質問を作成しました.いくつか調べて分かった箇所もあるので正しい理解か確認したいです.
・構造体のメンバ関数のようなもので構造体と同じ名前がついているもの
参考サイトは次の通りです.最後のものは理解できてないのですが初心者が犯しやすい間違いで参考にしています.
・ コンストラクタとメンバ初期化子リスト cppreference.com
・ メンバ初期化子リスト MaryCore
・ N1986 Delegating Constructors (revision 3)
具体的な質問内容
**1.**コンストラクタの本体とはどの部分で,どのようなコードでしょうか?
コンストラクタの本体(body)で共通処理の関数を呼び出していた。
理解
コンストラクタの本体は初期化子リストも含めた部分.共通処理の関数は CommonInit()
.
C++
1class X {...} 2 3class Y { 4 X a, b, c, d; 5public: 6 Y() { CommonInit(); } //「{ CommonInit(); }」がコンストラクタの本体 7 Y(X a_, X b_) : a(a_), b(b_) { CommonInit(); } //「a(a_), b(b_) { CommonInit(); }」がコンストラクタの本体 8 9 // 共通処理の関数 10 void CommonInit() { c = X(...); d = X(...); } 11};
2. 「パフォーマンスを阻害していた」とはどの部分ですか?
理解
初期化の順序としてコンストラクタの本体は非静的データメンバの初期化後に呼ばれるので,CommonInit()
内で非静的データメンバの初期化を行うと各データメンバのデフォルトコンストラクタが呼ばれた後に代入などの処理が行われ,デフォルトコンストラクタの呼び出しが冗長となりパフォーマンスを阻害していた.
**3.**下の箇所のコンストラクタごとに同じ処理を書くとはどのようなものですか?
パフォーマンスを維持するためには,コンストラクタごとに同じ処理を書く必要があり,コードの肥大化が問題となった
理解
メンバ初期化子リストでデータメンバの初期化を書くやり方はデフォルトコンストラクタを呼び出すのでパフォーマンスを維持する.ただ,これは初期化子リストのことで違う気がする.コンストラクタのブロック文に CommonInit()
をコピペする方法はコードの肥大化には当てはまるがパフォーマンスを維持するかは分からない.
C++
1class X {...} 2 3class Y { 4X a, b, c, d; 5public: 6 Y() : c(X(...)), d(X(...)) {} 7 Y(X a_, X b_) : a(a_), b(b_), c(X(...)), d(X(...)) {} 8};
4. 初心者が犯しやすい間違い次の例で i = 100
ではなく i = -1
が出力されるのは何故ですか?
C++
1class X { 2int i = -1; 3public: 4 X() { std::cout << "i = " << i << std::endl; } 5 X(int i_) : i(i_) { X(); } 6} 7 8int main() { 9 X x(100); 10 return 0; 11}
理解
分かりませんでした.
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/02/12 15:29