Effective C+.10,11 operator=の約束と注意
4536 ワード
1.reference to*thisを返します.
自身への参照を返す慣例は、(a=c)のように行うことができる.modify()と同様の操作、すなわちチェーン操作を形成することができ、そうでなければ変更は一時的なオブジェクトにすぎない.これはJavaでよく使われるビルダーモードと同じ理屈です
2.自己付与値の検出と異常安全
付与前に自己検出を行い,同様に直接返す.検出を行わないと、リソースのエラーが解放されやすく、コピーできなくなります(自分のリソースが解放されました).
もちろん、本の書き方通りにこれをもっと良い形式に変えることもできます.
つまり、新しいリソースが取得された後にレプリケーションが完了してから古いリソースの解放が行われることを確認します.
自身への参照を返す慣例は、(a=c)のように行うことができる.modify()と同様の操作、すなわちチェーン操作を形成することができ、そうでなければ変更は一時的なオブジェクトにすぎない.これはJavaでよく使われるビルダーモードと同じ理屈です
2.自己付与値の検出と異常安全
付与前に自己検出を行い,同様に直接返す.検出を行わないと、リソースのエラーが解放されやすく、コピーできなくなります(自分のリソースが解放されました).
class Data {
private:
int* data;
int len;
public:
Data(int cnt) {
if (cnt < 0) {
cnt = 0;
}
data = new int[cnt];
len = cnt;
}
Data& operator=(const Data& rhs) {
if (&rhs == this) {
return *this;
}
delete data;
data = new int[rhs.len];
for (int i=rhs.len; i>=0; i--) {
data[i] = rhs.data[i];
}
return *this;
}
void set(int idx, int value) {
if (idx >= len || idx < 0) {
return;
}
data[idx] = value;
}
int get(int idx) {
if (idx >= len || idx <0) {
return 0;
}
return data[idx];
}
};
もちろん、本の書き方通りにこれをもっと良い形式に変えることもできます.
Data& operator=(const Data& rhs) {
int* olddata = data;
int* newdata = new int[rhs.len];
for (int i=rhs.len; i>=0; i--) {
newdata[i] = rhs.data[i];
}
data = newdata;
delete olddata;
return *this;
}
つまり、新しいリソースが取得された後にレプリケーションが完了してから古いリソースの解放が行われることを確認します.