-
Notifications
You must be signed in to change notification settings - Fork 2
2014 06 09 대입 연산자의 필수 요소
krikit edited this page Nov 26, 2014
·
1 revision
대입 연산자를 만들 경우 자기 자신에게 대입하는 경우에 대하여 반드시 처리해야 합니다. 아래와 같은 코드를 한번 보시죠.
class MyClass {
public:
int* vec; // 포인터 멤버
MyClass& operator=(MyClass& that) {
if (this->vec != std::nullptr) delete this->vec;
this->vec = that->vec; // this == &that 이면 that->vec은 이미 dangling
that->vec = std::nullptr;
}
};
int main(int argc, char** argv) {
MyClass my_obj;
MyClass* my_ptr = &my_obj; // 여긴 그냥 포인터 초기화
*my_ptr = my_obj; // 대입 연산자 호출
return 0;
}
예제를 위해 극단적으로 썼습니다만, 객체 내에 힙에 할당된 포인터 멤버를 갖고 있고, 대입이 일어날 때 이 멤버를 다른 객체로 넘겨주는 식으로 힙에 할당된 메모리를 하나의 포인터만 가리키도록 유지하려는 것입니다.
그런데, 위 코드에서 this == &that
이면 대입 연산자의 두번째 코드에서 이미 메모리가 해제된 dangling 포인터를 주고 받는 상황이 발생합니다. 그래서 아래 코드처럼 대입 연산자를 오버라이딩할 경우 자기 자신에게 대입하는 경우를 검사하는 코드가 필수요소가 되겠습니다.
class MyClass {
public:
MyClass& operator=(MyClass& that) {
if (this == &that) return *this; // 필수 요소
...
}
}