アフィリエイト広告を利用しています

広告

posted by fanblog

2017年10月21日

《その87》 コンストラクタ初期化子


クラス型オブジェクトの生成過程について


 次の ClassA型のクラスは、Sub型のクラスをデータメンバとして持っています。
この ClassA型のクラスオブジェクトが生成される場合について考えてみます。

------------------------------------------------
class Sub {
int a, b;
public:
Sub() {}; // 1.
Sub(int a, int b);
};


class ClassA {
std::string str;
Sub sub;
public:
ClassA(std::string s, int a, int b) {
str = s;
sub = Sub(a, b); // 2.
}
};
------------------------------------------------



いま、ClassA型のオブジェクト aaa を作成するものとします。

ClassA aaa("abc", 10, 20);



【1】 メンバ str が "abc" で初期化されるまでの過程

(1) string型の str が生成される。

(2) string型のデフォルトコンストラクタが呼び出されて、データメンバ str が空文字列を
表すように初期化される。
※ 実際は、この (2) で本当の意味の初期化作業は完了し、あとは代入作業になります。

(3) コンストラクタ本体が実行され、仮引数 s に受け取った文字列 "abc" が、データメンバ str
に代入される。
具体的には、"abc" を格納できる大きさの記憶域を、new演算子で確保し直すことになります。

このように、かなりコストの高い手順が踏まれています。



【2】 クラス型メンバ sub が初期化されるまでの過程

(1) Sub型の sub が生成される。

(2) Sub型のデフォルトコンストラクタ(1.)が呼び出されて、クラス型データメンバ sub が
初期化される。
※ 実際は、この (2) で本当の意味の初期化作業は完了し、あとは代入作業になります。
※ デフォルトコンストラクタ(1.)がないとエラーになります。

(3) コンストラクタ本体が実行され、初期化済のデータメンバ sub に 10, 20 の値がセットされる。
具体的には、
sub = Sub(a, b);
の箇所で、まず、Sub型の一時オブジェクト Sub(10, 20) が作られ、それが sub に代入される
ことになります。

このように、かなりコストの高い手順が踏まれています。



コンストラクタ初期化子

上に記述した ClassA型のコンストラクタは、次のようなコードでした。

ClassA(std::string s, int a, int b) {
str = s;
sub = Sub(a, b);
}


これには、上述の【1】,【2】に書いたようなコスト的な問題がありました。
次のコードは、このコンストラクタを、コンストラクタ初期化子を用いて書きかえたものです。

ClassA(std::string s, int a, int b)
: str(s), sub(a, b)
{
};


下線の箇所がコンストラクタ初期化子です。全てのデータメンバに対してメンバ初期化子を与えたので、コンストラクタの本体部分が空になっています。

コンストラクタ初期化子を用いることで、
データメンバ string str や Sub sub を、【1】や【2】にある「代入」の手順を経ずに、直接、
初期化することができます。




以上の内容を、簡単なプログラムにまとめてみました。

#include <string>
#include <iostream>

class Sub {
int a, b;
public:
Sub() { a = 1; b = 2; }
Sub(int a, int b) {
this->a = a;
this->b = b;
}
int get_a() { return a; }
int get_b() { return b; }
};

class ClassA {
std::string str;
Sub sub;
public:
ClassA(std::string s, int a, int b)
: str(s), sub(a, b)
{}

int get_a() { return sub.get_a(); }
int get_b() { return sub.get_b(); }
std::string get_str() { return str; }
};

int main() {
ClassA aaa("衆議院議員総選挙", 1000, 2000);
std::cout << aaa.get_a() << '\n';
std::cout << aaa.get_b() << '\n';
std::cout << aaa.get_str() << '\n';
}

c11_9004.png


新版 明解C 入門編 (明解シリーズ)

新品価格
¥2,916から
(2017/8/30 21:02時点)









--
この記事へのコメント
コメントを書く

お名前:

メールアドレス:


ホームページアドレス:

コメント:

※ブログオーナーが承認したコメントのみ表示されます。

この記事へのトラックバックURL
https://fanblogs.jp/tb/6880357
※ブログオーナーが承認したトラックバックのみ表示されます。

この記事へのトラックバック

 たまに、クリック お願いします m(_ _)m

 AA にほんブログ村 IT技術ブログ C/C++へ

こうすけ:メール kousuke_cpp@outlook.jp

【1】★★C++ 記事目次★★ ← 利用可能です。
・新版明解C++入門編 / 新版明解C++中級編
・その他 C++ 関連記事

【2】★★こうすけ@C#★★
・C# の初歩的な記事


検索
<< 2018年08月 >>
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  
プロフィール
こうすけさんの画像
こうすけ

 たまに、クリック お願いします m(_ _)m

 AA にほんブログ村 IT技術ブログ C/C++へ

こうすけ:メール kousuke_cpp@outlook.jp

【1】★★C++ 記事目次★★ ← 利用可能です。
・新版明解C++入門編 / 新版明解C++中級編
・その他 C++ 関連記事

【2】★★こうすけ@C#★★
・C# の初歩的な記事


×

この広告は30日以上新しい記事の更新がないブログに表示されております。