メンバ変数
メンバ変数がクラスの場合の初期化
クラスのメンバ変数が引数付きのコンストラクタの場合、メンバイニシャライザを使ってコンストラクタを呼び出す。
クラスのメンバ変数の引数付きのコンストラクタの呼び出し方のメモ
コンストラクタ
コピーコンストラクタ
- コピーコンストラクタが呼ばれる時は、 ①オブジェクトの初期化時、②オブジェクトを関数に値渡しするとき、③ 関数からオブジェクトを値渡しする時
- コピーコンストラクタは代入では作用しない。Kitty obj; obj = g_obj; では呼ばれない。
- 関数にオブジェクトを渡したり、あるいは戻り値として受け取った場合、オブジェクトはビット単位でそっくりそのままコピーされる(デフォルトのコピーコンストラクタの場合)。
- 前途のように、引数に渡したインスタンスがコピーされる時、コピーコンストラクタが呼び出されるが、コピーコンストラクタの実装によっては、元のインスタンスと完全に同じデータが渡されるとは限らなくなります。
- 明示的的に定義しない時は、デフォルトのコピーコンストラクタがコールされる。デフォルトのコピーコンストラクタでは、メンバー変数もコピーしてくれる。明示的的に定義した場合は、コピーコンストラクタに必要であればメンバー変数のコピー処理を記述する必要がある。
- そのオブジェクトが動的に割り当てたメモリ領域へのポインタ型メンバ変数を保有していた場合、このポインタのアドレスも同じものを指すので、データの整合性が保てなくなる。また、それぞれのオブジェクトのデストラクタ関数で2度にわたって同じ領域が解放される危険性がある。
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 32 33 34 35 36 |
#include <iostream> using namespace std; class TestClass { public: TestClass() { cout << "コンストラクタ" << endl; V = 0; } virtual ~TestClass(){} //明示的にコピーコンストラクタを定義しない場合は、ディープコピーとなる。 TestClass(const TestClass& pObj){ cout << "コピーコンストラクタ" << endl; V = pObj.V; //明示的にコピーコンストラクタを定義した場合は、メンバー変数のコピー処理を記述する。 } int V; }; int main() { TestClass ta; //コンストラクタが呼ばれる ta.V=1; TestClass tb; //コンストラクタが呼ばれる tb = ta; //代入ではコピーコンストラクタは呼ばれない。ディープコピー ta.V = 9; cout << "ta = " << ta.V << endl; //9が表示される cout << "tb = " << tb.V << endl; //1が表示される。ディープコピーが行われている TestClass tc = ta; //コピーコンストラクタが呼ばれる cout << "tc = " << tc.V << endl; return 0; } |
引数
値渡しの場合はコピーされる(コピーコンストラクタが呼ばれる)。その変数が非常に大きなサイズを持つ構造体の場合、不必要なコピーを避ける目的でポインタが使われることがあるが、C++では、ポインタ渡しでなく、参照渡しとする。
参照したページ