스토리텔링 개발자

[Effective C++] 12. 복사 함수 구현 본문

개발/Effective C++

[Effective C++] 12. 복사 함수 구현

김디트 2024. 5. 31. 10:46
728x90

항목 12. 객체의 모든 부분을 빠짐 없이 복사하자

 

 

 

복사 함수(copying function)
  • 복사 생성자
  • 복사 대입 연산자

 

 

 

커스텀 복사 함수의 맹점
  • 컴파일러가 생성한 복사 함수의 경우
    • 복사되는 데이터가 갖는 데이터를 빠짐없이 복사한다.
  • 커스텀 복사 함수의 경우
    • 기존에 아무리 꼼꼼히 모든 멤버를 복사하도록 구현하더라도 클래스에 멤버가 추가되거나 하여 부분 복사가 될 여지가 있다.
    • 이 경우 컴파일러는 경고 하나 띄우지 않음
    • 즉 클래스에 데이터 멤버 추가 시 복사함수 / 생성자 / 비표준형 operator= 갱신을 해줘야 할 필요성이 있다.

 

 

 

클래스 상속의 커스텀 복사
class Customer // 기본 클래스
{
public:
    ...
private:
    std::string name;
    Data lastTransaction;
}

class PriorityCustomer : public Customer // 파생 클래스
{
public:
    ...
    PriorityCustomer(const PriorityCustomer& rhs);
    PriorityCustomer& operator=(const PriorityCustomer& rhs);
    ...
private:
    int priority;
}

PriorityCustomer::PriorityCustomer(const PriorityCustomer& rhs) : priority(rhs.prioryty)
{
    logCall("PriorityCustomer 복사 생성자");
}

PriorityCustomer& PriorityCustomer::operator=(const PriorityCustomer& rhs)
{
    logCall("PriorityCustomer 복사 대입 연산자");
    
    priority = rhs.priority;
    
    return *this;
}
  • 위의 코드는 파생 클래스가 기본 클래스의 데이터는 복사하지 않는 실수를 하고 있다.
  • 상속시 파생 클래스의 데이터 뿐 아니라 기본 클래스의 데이터도 챙겨줘야 한다.
    • 복사 함수 안에서 기본 클래스의 대응되는 복사 함수를 호출해야 한다.
PriorityCustomer::PriorityCustomer(const PriorityCustomer& rhs) : Customer(rhs), // 기본 클래스의 복사 생성자 호출
                                                                  priority(rhs.prioryty)
{
    logCall("PriorityCustomer 복사 생성자");
}

PriorityCustomer& PriorityCustomer::operator=(const PriorityCustomer& rhs)
{
    logCall("PriorityCustomer 복사 대입 연산자");
    
    Customer::operator=(rhs); // 기본 클래스 부분을 대입
    priority = rhs.priority;
    
    return *this;
}

 

 

 

복사 함수끼리의 코드 중복 회피?
  • 복사 함수의 코드 중복을 피하기 위해 한쪽에서 다른 한쪽을 호출하는 건 어불성설이다.
    • 복사 대입 연산자에서 복사 생성자 호출
      • 이미 존재하는 객체에 대해 생성한다?
      • 더군다나 이렇게 호출할 방법도 없다.
    • 복사 생성자에서 복사 대입 연산자 호출
      • 이미 초기화된 객체에 값을 할당하는 함수를 생성중인 객체에?
  • 해결법
    • 양 쪽에서 겹치는 부분을 별도의 멤버 함수로 분리하여 호출해주자.
728x90
Comments