본문 바로가기

Effective C++/2. 생성자, 소멸자 및 대입 연산자

항목 5: C++가 은근슬쩍 만들어 호출해 버리는 함수들에 촉각을 세우자.

객체지향 C++에서 클래스 안에 직접 선언해 넣지 않으면 컴파일러가 저절로 선언해 주도록 하는 맴버 함수들 있다.

 

  • copy constructor
  • copy assignment opeartor
  • destructor
  • default constructor

 

이때 맴버함수들은 모두 기본형, public, inline 함수이다.

 

컴파일러가 만들어주는 함수들은 무슨역할을 할까?

 

=> 컴파일러에게 "배후의 코드" 있는 자리를 마련하는 것이다.

 

배후의 코드 = base class non-static member 생성자, 소멸자를 호출하는 코드

 

소멸자는 derived class 상속한 base class 소멸자가 virtual 되있지 않으면 역시 non-virtual 소멸자로 만들어진다는

 

복사 생성자, 복사 대입생성자는? => 원본 객체의 non-static member들을 copy 객체쪽으로 복사하는 것이다.

 

 

 

생성자가 선언되있음 => 기본생성자는 만들어지지 않음

 

복사 생성자는 생성되있지 않기 때문에, 기본 복사 생성자 생성 호출

 

기본 복사 생성자는 어떻게 동작할까?

=> no1.nameValue no1.objectValue 사용해 no2.nameValue no2.objectValue 초기화 해야한다.

 

nameValue type string, 표준 string type 자체 복사 생성자가 있으므로 no2.nameValue 초기화는 string 복사 생성자에 no1.nameValue 넘겨 호출한다.

 

string nameValue(no1.nameValue);  이렇게 동작

 

objectValue built-in type 이므로 복사 생성자가 없다. 그냥 bit 복사하고 끝남

 

int objectValue(no1.obejctValue);

 

 

기본 복사 대입 연산자는 어떻게 동작할까?

 

근본적인 동작원리는 기본 복사 생성자와 같음

하지만 기본 복사 대입 연산자는 몇가지 조건이 통과되어야 생성됨

 

 

 

 

아까랑 다른게 nameValue string 아니라 string& 이다. 참조자로 선언됨

 

근본적인 원리가 기본 복사 생성자와 같다면

 

p = s; 에서 p 객체에서는 p.nameValue = s.nameValue;  일어 나야됨 => 말이 안된다.

 

p.nameValue 이미  newDog 가르키고 있기 때문이다.

 

C++ 참조자는 원래 자신이 참조하고 있는 것과 다른 객체를 참조할 수 없다!!! 갈아타기 안됨

 

 

참조자를 데이터 맴버로 갖고 있는 클래스에 대입 연산 지원하려면, 우리가 직접 복사 대입 연산자를 정의해줘야한다. >> 이게 기본 복사 대입 연산자의 생성 조건임, 조건에 어긋나면 컴파일 에러다.

 

데이터 맴버가 상수 객체 경우( const T objectValue; )에도 비슷하게 동작한다.

 

정리하 데이터 맴버가 참조자, 상수 객체 경우 직접 복사 대입 연산자를 정의해야 한다.

 

그리고 복사 대입 연산자를 private으로 선언한 base class로부터 상속받은 derived class 경우에도 기본 복사 대입 연산자를 생성할 없다.

 

 

 

  • 컴파일러는 경우에 따라 클래스에 대해 기본 생성자, 복사 생성자, 복사 대입 연산자, 소멸자를 암시적으로 만들어 놓는다.