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

빈 클래스가 눈으로는 아무것도 없어보이지만 실제로는 컴파일러가 자동으로 생성해준 함수들이 있다. 바로 기본 생성자(default constructor), 복사 생성자(copy constructor), 복사 대입 연산자(copy assignment operator), 소멸자(destructor) 이렇게 네 가지가 있다. 이 형태는 전부 기본형이며 public 그리고 inline으로 선언된다.

class Empty {};

위 코드와 아래 코드는 근본적으로 동일하다.

class Empty {
public:
    Empty() {} // 기본 생성자
    Empty(const Empty& rhs) {} // 복사 생성자
    Empty& operator=(const Empty& rhs) {} // 복사 대입 연산자
    ~Empty() {} // 소멸자
};

실제로 사용되는 코드는 다음과 같다.

Empty e1; // 기본 생성자 호출, 소멸자
Empty e2(e1); // 복사 생성자 호출
e2 = e1; // 복사 대입 연산자 호출

컴파일러가 생성한 생성자와 소멸자는 기본적으로 일차적으로 컴파일러에게 “배후의 코드”를 깔 수 있는 자리를 마련하는 것이고 복사 생성자와 복사 대입 연산자의 경우엔 원본 객체의 비정적 데이터를 사본 객체 쪽으로 그냥 복사하는 것이다.

다만 컴파일러가 만든 복사 대입 연산자의 동작이 적법해야 하고 이치에 닿아야만 자동생성을 받을 수 있다. 만약 일치하지 않는다면 컴파일 에러가 날 수 있다. 참조자를 데이터 멤버로 가지고 있는 경우에는 직접 복사 대입 연산자를 정의해 주어야 한다.

추가로 복사 대입 연산자를 private으로 선언한 기본 클래스로부터 파생된 클래스의 경우, 이 클래스는 암시적 복사 대입 연산자를 가질 수 없다. 컴파일러가 거부하기 때문이다.

정리

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

느낀점

Cpp의 가장 기본적인 지식이지만 많이 놓치기도 하고 헷갈리는 부분이라 명확하게 정리하고 가는 부분이 좋은 것 같다. 실제로 면접에서도 많이 물어보는 것 같다.

태그: ,

카테고리:

업데이트:

댓글남기기