Notice
Recent Posts
Recent Comments
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
Tags
- map
- BFS
- 알고리즘
- UELOG
- enumasByue
- UML관련
- UE4 커스텀로그
- C++최적화
- 언리얼가비지컬렉터
- 정렬
- 람다사용정렬
- 스마트포인터
- UE_LOG
- moreeffectiveC++
- 선택정렬
- 델리게이트
- 강참조
- 프로그래머스
- stl
- 정렬알고리즘
- 약참조
- 데이터애셋
- 람다
- 애셋로드
- unorder_map
- 언리얼엔진구조체
- dataasset
- 크리티컬섹션
- C++
- 자료구조
Archives
- Today
- Total
기억을 위한 기록들
[CPP-effective] 2-6 operator=에는 자기대입에 대한 처리를 빼먹지 말자. 본문
자기대입(self assignment)란, 어떤 객체가 자기 자신에 대해 대입 연산자를 적용하는 것을 말합니다.
class Widget{...};
Widget myWidget;
myWidget=myWidget;
보통 위와같은 식을 말하는데 이외에도
a[i]=a[j]; //i와 j가 같을수도 있다.
*px=*py; //자기대입 가능성이 아주 높다,
px와 py가 가리키는 대상이 같아지면 여러곳에서 하나의 객체를 참조하는상태 즉 중복참조(aliasing)이라고 불린다.
이외에도 자식부모 클래스의 상속관계 있는 클래스 사이에서도 중복 참조는 일어 날수도 있다.
class Base{..};
class Player : public Base {...};
void DoSomething(const Base& rb, Player* p1); //rb와 *p1은 같은 객체 였을수도 있다.
이런 자기 대입이 일어날때 중복참조라던가 자원 관리 객체들이 복사될 때 잘 작동해야하는데, 그 중 조심해야 할것이 바로, 대입 연사자 operator= 이다.
일단 안전하지 않은 대입연산자를 먼저 보자.
class Player{
///..
Player& operator=(const Player& ref);
private:
char* mPlayerName;
};
Player& Player::operator=(const Player& ref) //불안전하다.
{
delete mPlayerName;
mPlayerName = new char(*ref.mPlayerName);
return *this;
}
여기서 생기는 자기 참조 문제는 operator= 내부에서 대입되는 대상과 ref 객체가 같은 객체일 가능성이 있다는 것이다.
이것을 해소해줄게 전통적인 방벙니 일치성 검사(identity test)를 통해 자기대입을 점검하는 것이다.
class Player{
///..
Player& operator=(const Player& ref);
private:
char* mPlayerName;
};
Player& Player::operator=(const Player& ref)
{
if(this == &ref) //일치성 검사
return *this;
delete mPlayerName;
mPlayerName = new char(*ref.mPlayerName);
return *this;
}
이렇게 자기대입인지 검사하는 방법이외에도 추가로 '복사 후 맞 바꾸기(copy and swap)'이라고 알려진 기법도 간략히 설명하자면,
class Player{
///..
void swap(Player& ref);
Player& operator=(const Player& ref);
private:
char* mPlayerName;
};
Player& Player::operator=(const Player& ref)
{
Player tempPlayer(ref); //ref의 데이터에 대해 사본을 만든다.
swap(tempPlayer); //*this의 데이터와 그 사본과 서로 맞바꾼다.
return *this;
}
정리
* operator=을 구현할 때, 어떤 객체가 그 자신에 대입되는 경우를 제대로 처리하도록 만들자. 원본 객체와 복사대상 객체의 주소를 비교해도 되고, 문장이 순서를 적절히 조절할 수도 있으며, 복사 후 맞바꾸기 기법을 써도 된다.
* 두 개 이상의 객체에 대해 동작하는 함수가 있다면, 이 함수에 넘겨지는 객체들이 사실 같은 객체인 경우에 정확하게 동작하는지 확인해보자.
'C & CPP > Effective C++' 카테고리의 다른 글
[CPP-effective] 3-1 자원 관리에는 객체가 그만! (0) | 2021.04.01 |
---|---|
[CPP-effective] 2-7 객체의 모든 부분을 빠짐없이 복사하자. (0) | 2021.03.30 |
[CPP-effective] 2-5 대입 연산자는 *this의 참조자를 반환하게 하도록 (0) | 2021.03.22 |
[CPP-effective] 2-4 객체 생성/소멸 과정 중에는 가상함수를 호출하지말자. (0) | 2021.03.22 |
[CPP-effective] 2-3 예외가 소멸자를 떠나지 못하도록 붙들어 놓자.(보류) (0) | 2021.03.15 |