constメンバ変数を含むオブジェクトの代入
実は前回の記事で書いたプログラムをコンパイルすると下記のような警告が出ていました。
main.cpp main.cpp(9) : warning C4512: 'CSample' : 代入演算子を生成できません。 main.cpp(4) : 'CSample' の宣言を確認してください。
最初なんのことか分からなかったのですが、constメンバ変数が含まれているという部分でピンときました。
通常C++ではオブジェクト同士の代入が可能なのですが、constメンバ変数が含まれていると、値の代入ができないためコンパイルエラーとなるのです。
#include <iostream> using namespace std; class CSample { public: const int m_num; CSample(int num); }; CSample::CSample (int num) : m_num(num) { } int main() { CSample obj1(100); CSample obj2(200); obj1 = obj2; // 代入できない! cout << obj1.m_num << endl; cout << obj2.m_num << endl; return 0; }
$ cl /W4 /EHsc main.cpp Microsoft(R) 32-bit C/C++ Optimizing Compiler Version 15.00.30729.01 for 80x86 Copyright (C) Microsoft Corporation. All rights reserved. main.cpp main.cpp(9) : warning C4512: 'CSample' : 代入演算子を生成できません。 main.cpp(5) : 'CSample' の宣言を確認してください。 main.cpp(18) : error C2582: 'operator '=' 関数を 'CSample' で使用できません。
つまり、constメンバ変数を用意するということは、代入演算子が使われた場合の振る舞いを定義しておかないとダメだということになります。
#include <iostream> using namespace std; class CSample { public: const int m_cnum; int m_num; CSample(int num); CSample& operator=(const CSample& obj); }; CSample::CSample (int num) : m_cnum(num) { m_num = num; } CSample& CSample::operator=(const CSample& obj) { // m_numだけコピー。m_cnumはconstなのでコピーしない this->m_num = obj.m_num; return *this; } int main() { CSample obj1(100); CSample obj2(200); obj1 = obj2; cout << "obj1.m_num = " << obj1.m_num << endl; cout << "obj1.m_cnum = " << obj1.m_cnum << endl; cout << "obj2.m_num = " << obj2.m_num << endl; cout << "obj2.m_cnum = " << obj2.m_cnum << endl; return 0; }
$ main obj1.m_num = 200 obj1.m_cnum = 100 obj2.m_num = 200 obj2.m_cnum = 200
と、いったような感じになります。
しかし、こういった事情もあるのでそもそもconstメンバ変数を持っているようなオブジェクトに対して、代入処理をするようなこと自体間違っているんじゃないかなという気はします。