Effective C++ Operator = 에서는 자기 대입에 대한 처리가 빠지지 않도록 하라
C++/C++ 2021. 6. 27. 00:57 |Do not take away the processing of self-admission in Operator=
operator= 라는 대입 연산자를 구현할 때, 객체가 자신에게 대입되는 경우에 대한 처리를 하도록 해야한다.
이러한 처리를 위해서 자기 자신과의 주소를 비교하거나 복사 후 바꾸는 방법을 사용하면 된다.
즉, 어떤 객체가 자기 자신에 대해 대입연산사를 사용하는 자기대입을 조심해야 한다.
class Bitmap {
public:
Bitmap(int r, int g, int b) {
this->r = r;
this->g = g;
this->b = b;
}
private:
int r;
int g;
int b;
};
class Widget {
public:
Bitmap *bitmap;
Widget& operator= (const Widget& whs){
delete(bitmap);
this->bitmap = whs.bitmap;
}
};
만약 위의 코드를 아래와 같이 호출한다면 문제가 발생한다.
Widget *temp;
void func(Widget widget) {
Widget r = *temp;
r = widget;
}
int main() {
Widget *widget = new Widget();
widget->bitmap = new Bitmap(1, 5, 3);
temp = widget;
func(*widget); // 에러
}
func라는 함수 내부에서 r과 widget은 같은 객체를 뜻하기 때문에 위의 operator=이 불리게 된다. 따라서 Bitmap객체를 delete하고, 두 r과 widget 객체 모두 bitmap을 잃어버리게 되는것이다.
그렇기 때문에 operater을 구현 할 때에는 자기 대입에 대한 처리가 빠져선 안된다.
Widget& Widget::operator= (const Widget& whs) {//여기서 &는 참조(reference)
if(this == &whs) return *this;//여기서 &는 주소값
delete(bitmap);
this->bitmap = whs.bitmap;
}
같은 객체인지에 대한 예외처리를 통해 문제 발생을 차단 하자.
'C++ > C++' 카테고리의 다른 글
[exception specifier] noexcept (0) | 2021.07.11 |
---|---|
TLS(Thread Local Storage) (0) | 2021.06.27 |
Effective C++ 객체 생성 및 소멸 과정 중에는 가상 함수를 호출하지 말라 (0) | 2021.06.27 |
Effective C++ 컴파일러가 만든 함수가 필요 없는 경우 이를 제거하라 (0) | 2021.06.27 |
Effective C++ 상속된 클래스가 있는 경우 가상 소멸자를 사용 (0) | 2021.06.27 |