読者です 読者をやめる 読者になる 読者になる

代入演算子のオーバーロード

C++

コピーコンストラクタの項で、「オブジェクトの代入は、コピーではあるがコピーコンストラクタの対象外で、この場合コピー代入演算子オーバーロードが必要」ということを書いた・・・。
このオブジェクトの代入の場合も、アドレスのコピーをしないようにコピー処理を書かなければならない・・・。
今回はオブジェクトを代入した時の処理を、代入演算子オーバーロードで定義する・・・。

profile.hで、

これが代入演算子オーバーロード・・・。
引数のobjが左辺のオブジェクト参照でこれを元に新しいメモリを確保してコピーする処理を書かないといけない・・・。

profile.cppは、

実態としては、objの各メンバをset_profileに渡して呼んでいるだけ・・・。
でset_profileで、

すでにセットされている場合はいったん解放して、また確保してコピーという感じ・・・。
それぞれ、どの関数が呼ばれたか一応出力するようにしている・・・。

main.cppは、

まず、obj1に"Taro"、20、"Tokyo"をセット・・・。
obj1のメンバをいったん出力・・・。
次に、obj2をobj1で初期化・・・。
この場合はコピーコンストラクタでコピーされる・・・。
obj2を出力・・・。
続いてobj3は、"Jiro"、18、"Osaka"という全く違うデータをセット・・・。
obj3を出力・・・。
最後にobj3にobj2を代入する・・・。
この時、ようやく代入演算子オーバーロードが呼ばれる・・・。
これでobj3を出力・・・。

すると、

$ g++ -o main main.cpp profile.cpp
$ ./main
constructor
set_profile
get_name
obj1.get_name() = Taro
get_age
obj1.get_age() = 20
get_address
obj1.get_address() = Tokyo
copy_constructor
get_name
obj2.get_name() = Taro
get_age
obj2.get_age() = 20
get_address
obj2.get_address() = Tokyo
constructor
set_profile
get_name
obj3.get_name() = Jiro
get_age
obj3.get_age() = 18
get_address
obj3.get_address() = Osaka
set_profile
assignment_operator_overload
get_name
obj3.get_name() = Taro
get_age
obj3.get_age() = 20
get_address
obj3.get_address() = Tokyo
before delete [] name_ = 0x1ba40b0
before delete [] address_ = 0x1ba4090
destructor
before delete [] name_ = 0x1ba4050
before delete [] address_ = 0x1ba4070
destructor
before delete [] name_ = 0x1ba4010
before delete [] address_ = 0x1ba4030
destructor
$

obj3にJiro、18、Osakaをセットした後に、obj2を代入するところでassignment_operator_overloadが呼ばれている・・・。
その後、obj3は見事にobj2と同じTaro、20、Tokyoとなり、それぞれのデストラクタでもきちんとメモリは解放されている・・・。

Sample/cpp/assignment_operator_overload/assignment_operator_overload/src/assignment_operator_overload at master · bg1bgst333/Sample · GitHub