책 정리/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 함수를 구현하여 호출하도록 만든다.