클래스는 복사 생성자, 복사 대입, 이동 생성자, 이동 대입, 소멸자라는 다섯 특별 멤버를 가질 수 있다. 자원이 없으면 컴파일러가 만든 것으로 충분하다. 이것을 0의 규칙이라고 부른다.

C++ 16. 복사, 이동, 다섯 가지 특별 멤버의 핵심 흐름도
그림. 직접 자원을 소유하면 복사·이동·소멸 정책을 함께 정한다.

소유가 하나일 때

class Buffer {
public:
    Buffer() = default;
    Buffer(const Buffer&) = delete;
    Buffer& operator=(const Buffer&) = delete;
    Buffer(Buffer&&) noexcept = default;
    Buffer& operator=(Buffer&&) noexcept = default;
    ~Buffer() = default;
private:
    std::unique_ptr<int[]> data_;
};

복사를 지우면 그 객체는 복제되지 않는다. 이동은 소유권을 넘긴다. 이동 생성은 `noexcept`인 편이 좋다. `vector`가 재할당할 때 이동이 예외를 던질 수 있다고 보면 복사를 선택하기 때문이다.

이동된 뒤의 상태

이동된 객체는 유효하지만, 그 안의 값이 무엇인지는 타입마다 정한다. 표준 라이브러리 타입은 그 상태에서 대입과 소멸이 가능하다. 사용자 타입도 그 정도를 보장하지 않으면 컨테이너 안에서 쓸 수 없다.

특별 멤버를 직접 쓰기보다 `unique_ptr`이나 `vector`처럼 이미 규칙을 지키는 멤버에 소유를 맡기면, 클래스 자신은 다시 0의 규칙으로 돌아온다.