The rule of five/zero

C++11부터 이동 생성자, 이동 대입 연산자를 지원함에 따라 컴파일러가 자동으로 생성해 주는 함수(Compiler-generated Functions, 이하 CGF)들이 늘어 났다. 본 글에서는 5가지의 CGF를 작성하는 규칙에 관한 내용이다.


5-CGF


컴파일러는 프로그래머가 5-CGF를 명시적으로 작성하지 않아도 자동으로 생성해주지만, 예외가 있다.


The rule of five/zero

Martinho Fernandes와 Scott Meyers는 자신의 블로그에 the rule of zero와 the rule of five default를 각각 제안 하였다.

The Rule of Zero

Rule of Zero by Martinho Fernandes: Classes that have custom destructors, copy/move constructors or copy/move assignment operators should deal exclusively with ownership. Other classes should not have custom destructors, copy/move constructors or copy/move assignment operators

핵심은 모든 클래스를 아래 둘 중 하나로 작성하라는 것이다.

#1. 5-CGF를 모두 작성한 클래스

class X {
public:
  ~X() = { /// };
  X(const X&) = default;
  X(X&&) = default;
  X& operator=(const X&) = default;
  X& operator=(X&&) = default;
  /// member functions
};

#2. 5-CGF를 모두 작성하지 않은 클래스

class X {
  /// member functions
};

The Rule of Five Default

Rule of the Five Defaults: Classes that declare custom destructors, copy/move constructors or copy/move assignment operators should deal exclusively with ownership. All other classes should explicitly default their destructors, copy/move constructors and copy/move assignment operators.

이 규칙의 핵심은x모든 클래스의 5-CGF를 구현 되어야 한다는 것이다. 구현이 필요 없는 경우(trivial)도 “= default”로 작성 하라는 것이다. (디버그용이나 나중에 5-CGF 중 하나를 구현하게 되었을 때를 대비)

class X {
public:
  ~X() = { /// };
  X(const X&) = default;
  X(X&&) = default;
  X& operator=(const X&) = default;
  X& operator=(X&&) = default;
  /// member functions
};

이 외에도 비슷한 맥락으로 The Rule of All or Nothing와 같이 각자의 견해로 5-CGF에 대한 규칙을 정하고 있다.


The point

유사한 방식으로 여러가지의 규칙을 정의하고 구현에 관한 가이드라인을 제공한다. 각각의 규칙에는 장단점과 많은 논의가 있다.

하지만 이 규칙들에서 말하고자하는 명백한 것은 “소멸자만 따로 정의함에 있어 컴파일러가 이동 생성자/대입연산자를 자동으로 생성하지 못하게 하는 것을 방지하라.”이다.

즉, 이동 시맨틱을 지원하지 않는 C++ 코드를 짜는 우를 범하지 마라. 는 것