代入と複製

  C++ 標準ライブラリ内の vector クラスを使用した C++ のプログラム例を載せておきます(出力結果は同じであるため除く).その際,出力文「 cout << 」に対しては,以下に示すように,<< 演算子のオーバーロードがされているものとします.
ostream& operator << (ostream& stream, vector<int> &s)
{
	if (s.empty())
		stream << "[]\n";
	else {
		stream << "[";
		for (unsigned int i1 = 0; i1 < s.size(); i1++) {
			stream << s[i1];
			if (i1 < s.size()-1)
				stream << ", ";
		}
		stream << "]\n";
	}
	return stream;
}
		

C/C++ における代入操作

			// 通常の代入
01	vector<int> s1, s2;
02	for(int i1 = 1; i1 <= 3; i1++)
03		s1.push_back(i1);
04	s2 = s1;
05	s2[0] = 10;
06	cout << s1;
07	cout << s2;
			// ポインタの代入
08	vector<int> *ps1, *ps2;
09	ps1 = &s1;
10	ps2 = ps1;
11	(*ps2)[0] = 10;
12	cout << *ps1;   // cout << s1; でも同じ
13	cout << *ps2;
			// 通常の代入( 2 次元配列)
14	vector<int> s3[2], s4[2];
15	for(int i1 = 1; i1 <= 3; i1++)
16		s3[0].push_back(i1);
17	for(int i1 = 4; i1 <= 6; i1++)
18		s3[1].push_back(i1);
19					// s4 = s3; はできない
20	for(int i1 = 0; i1 < 2; i1++) {
21		for(int i2 = 0; i2 < 3; i2++)
22			s4[i1] = s3[i1];
23	}
24	s4[0][0] = 10;
25	cout << s3[0];
26	cout << s4[0];
			// new 演算子の使用( 2 次元配列)
27	vector<int> *s5 = new vector<int> [2], *s6;
28	for(int i1 = 1; i1 <= 3; i1++)
29		s5[0].push_back(i1);
30	for(int i1 = 4; i1 <= 6; i1++)
31		s5[1].push_back(i1);
32	s6 = s5;
33	s6[0][0] = 10;
34	cout << s5[0];
35	cout << s6[0];
		
01 行目~ 07 行目

  04 行目において,表面的には,Python の場合と同様の代入を行っています.しかし,C++ の場合は,オブジェクト自身がコピーされるため,s2 の値を変更しても,s1 の値は変化しません.06,07 行目の出力結果は以下に示すとおりです.

  [1, 2, 3]
  [10, 2, 3]

08 行目~ 13 行目

  ps1 に s1 のアドレスを代入し( 09 行目),それを ps2 に代入しています.ps1 と ps2 は同じ場所を指しているため,Python の場合と同様,ps2 を介して値を変更すると( 11 行目),s1 の値も変化します.これが,ほぼ,Python における単純な代入に相当します.12,13 行目の出力結果は以下に示すとおりです.

  [10, 2, 3]
  [10, 2, 3]

14 行目~ 26 行目

  オブジェクト内に他のオブジェクトが存在する場合です.s3,s4 は 1 次元配列ですが,配列の各要素が vector クラスのオブジェクトであるため,2 次元配列のような働きになります.配列に対して,s4 = s3 のような代入ができないため,20 行目~ 23 行目のような処理を行っています.この場合も,s4 の値を変更しても,s3 の値は変化しません.25,26 行目の出力結果は以下に示すとおりです.なお,下の図は,24 行目を実行する前の状態です.

  [1, 2, 3]
  [10, 2, 3]

27 行目~ 35 行目

  上と同じような配列を new 演算子を使用して生成した場合です.この場合は,s6 及び s5 がポインタであるため,s6 = s5 のような代入が可能となります.その結果,s6 と s5 は同じデータを指すことになり,s6 を介して値を変更すると,s5 が指す値も変化します.34,35 行目の出力結果は以下に示すとおりです.なお,下の図は,33 行目を実行する前の状態です.

  [10, 2, 3]
  [10, 2, 3]