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

2022. 9. 8. 16:26·STUDY/Effective C++

복사생성자와 복사대입연산자를 통틀어 객체 복사 함수(copy function)이라고한다. 객체 복사함수는 컴파일러가 자동으로 만들어내기도하며 복사되는 객체가 갖고있는 데이터를 빠짐없이 복사하는 동작을하고있다.

 

하지만 컴파일러가 아닌 우리가 객체 복사함수를 만드는것이 컴파일러에게는 꽤나 기분이 나쁠 수도있다. 그래서 우리에게 복사함수 구현이 틀려도 조용히 있을경우가 있다.

 

class Customer{
public:
	...
	Customner(const Customer& rhs);
	Customer& operator=(const Customer& rhs);
	...
private:
	std::string name;
};



Customer::Customer(const Customer& rhs)
: name(rhs.name) //rhs데이터 복사
{
	logCall("customer copy constructor");
}

Customer& Customer::oprator=(const Customer& rhs)
{
	loCall("Customer copy assignment operator");
	name = rhs.name; //rhs데이터 복사
	return *this;
}

복사함수를 직접 구현하였을 경우의 클래스이다. 문제될것이 없어보이지만 여기서 데이터 멤버 하나를 추가하면 문제가 생기기 시작한다.

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.priority) //rhs데이터 복사
{
	logCall("PriorityCustomer copy constructor");
}

PriorityCustomer& PriorityCustomer::oprator=(const PriorityCustomer& rhs)
{
	loCall("PriorityCustomer copy assignment operator");
	priority = rhs.priority; //rhs데이터 복사
	return *this;
}

PriorityCustomer를 복사하는것같지만, 사실 Customer로부터 상속한 데이터 멤버들은 복사가 되지않고있다.

그나마 복사생성자에서는 Customer에서 상속한 name이나 lastTransaction을 초기화해주겠지만, 복사 대입연산자에서는 기본 클래스 데이터 멤버가 변경되지않고 그대로 있게된다.

 

PriorityCustomer::PriorityCustomer(const PriorityCustomer& rhs)
: Customer(rhs), ////////기본 클래스의 복사 생성자 호출
	priority(rhs.priority) 
{
	logCall("PriorityCustomer copy constructor");
}

PriorityCustomer& PriorityCustomer::oprator=(const PriorityCustomer& rhs)
{
	loCall("PriorityCustomer copy assignment operator");
    ////////////////////기본 클래스 부분 대입
    Customer::operator=(rhs);
    /////////////////////
	priority = rhs.priority; 
	return *this;
}

그럴 경우에는 기본 클래스의 복사 생성자를 호출하거나, 기본 클래스 부분을 대입하면된다. 객체 복사함수는 주어진 객체의 모든 데이터 멤버 및 모든 기본 클래스 부분을 빠트리지말고 복사해야한다. 

'STUDY > Effective C++' 카테고리의 다른 글

항목 14: 자원 관리 클래스의 복사 동작에 대해 진지하게 고찰하자  (0) 2022.10.28
항목 13: 자원관리에는 객체가 그만!  (2) 2022.09.22
항목 11: operator=에서는 자기대입에 대한 처리가 빠지지 않도록 하자  (0) 2022.08.31
항목 10 : 대입 연산자는 *this의 참조자를 반환하게 하자  (0) 2022.08.24
항목 9 : 객체 생성 및 소멸 과정 중에는 절대로 가상 함수를 호출하지 말자  (0) 2022.08.17
'STUDY/Effective C++' 카테고리의 다른 글
  • 항목 14: 자원 관리 클래스의 복사 동작에 대해 진지하게 고찰하자
  • 항목 13: 자원관리에는 객체가 그만!
  • 항목 11: operator=에서는 자기대입에 대한 처리가 빠지지 않도록 하자
  • 항목 10 : 대입 연산자는 *this의 참조자를 반환하게 하자
wise_
wise_
  • wise_
    WHY'S BlOG
    wise_
  • 전체
    오늘
    어제
    • 분류 전체보기 (63)
      • PROJECT (19)
        • 젯슨나노 프로젝트 (0)
        • 유니티 (9)
      • STUDY (37)
        • 코딩문제 (13)
        • 알고리즘 (0)
        • Effective C++ (14)
        • 유니티 (8)
        • 언리얼 (2)
      • ERROR (7)
        • 오류덩어리들 (7)
      • REVIEW (0)
      • LIFE (0)
        • 작고 소중한 내 일상 (0)
        • 작고 귀여운 내 취미 (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    귀여운
    unity
    퍼즐게임
    TheFoxSeeksFriend
    C++
    언리얼
    힐링게임
    유니티
    와이즌
    게임개발
    null
    개발
    인디게임
    error
    힐링
    스마일게이트
    백준
    ==
    개발일지
    알고리즘
    모바일게임
    wisen
    게임
    플로이드와샬
    윈터데브캠프
    c#
    깊이우선탐색
    코딩
    여우는오늘도친구를구한다
    1인개발
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
wise_
항목 12: 객체의 모든 부분을 빠짐없이 복사하자
상단으로

티스토리툴바