책 정리/Effective C++ 3rd
항목 12. 객체의 모든 부분을 빠짐없이 복사하자
ocean20
2019. 12. 18. 12:23
복사 함수란?
복사함수 = 복사 대입 연산자 + 복사 생성자
항목5에서 확인할 수 있듯이, 객체 복사 함수는 컴파일러에 의해 자동생성된다.
따라서 복사함수를 정의한다는 것은 기본 복사함수가 맘에 안든다는뜻이다.
컴파일러는 이러한 사용자의 행동이 틀려도(구현이 엉망이어도) 입을 닫는다.
Class Customer{
private :
string name;
public :
Customer(const Customer& rhs);
Customer& operator =(const Customer& rhs);
};
위 예시에서 멤버 변수 age가 추가된다면, 복사함수, 복사생성자에서 age에 대한 복사내용을 추가적으로 구현해야한다.
(구현하지 않아도 컴파일러는.. 알려주지않고 정상이라고 말한다..)
또한, 파생클래스에서 복사함수를 구현하는 방법을 확인해보자.
class PriorityCustomer : public Customer {
public:
…
PriorityCustomer(const PriorityCustomer& rhs);
PriorityCustomer& operator=(const PriorityCustomer& rhs);
private:
int priority;
};
PriorityCustomer::PriorityCustomer(const PriorityCustomer& rhs)
: Customer(rhs) // 파생클래스에서 기본클래스의 복사생성자를 호출한다.
,priority(rhs.priority)
{
…
}
PriorityCustomer& PriorityCustomer::operator=(const PriorityCustomer& rhs)
{
Customer::operator=(rhs); // 기본클래스 부분을 대입합니다.
priority = rhs.priority; // 파생클래스의 멤버변수를 대입합니다.
return *this;
}
* 결론 : 상속을 구현할때 해당클래스의 데이터 멤버 변수 뿐만 아니라, 기본클래스의 복사함수도 꼬박꼬박호출합시다.
Q. 복사 대입연산자에서 복사 생성자를 호출?
A. 안된다.
(1) 대입연산자의 역할 : 이미 초기화가 끝난 객체에게 값을 주는것
(2) 생성자의 역할 : 객체를 초기화하는것
- 그렇기 때문에 애초에 말이안된다.
(3) 두 복사함수의 코드 본문이 비슷하다면 제3의 함수에 작성하여 코드 중복을 피한다.
이것만은 잊지 말자!
1. 객체 복사 함수는 주어진 객체의 모든 데이터 멤버 및 기본클래스 부분을 빠뜨리지 않고 복사해야한다.
2. 복사함수를 구현할때, 한쪽을 이용해 다른쪽을 구현하려 하지 말자. 만약, 중복된 동작은 제3의 함수를 구현하여 호출하도록 만든다.