[C++] 항목 6: 컴파일러가 만들어낸 함수가 필요 없으면 확실히 이들의 사용을 금해 버리자
카테고리: cpp
태그: cpp
이 글은 아래의 책을 정리하였습니다.
이펙티브 C++ 제3판, 스콧 마이어스 저자, 곽용재 번역
📦 2. 생성자, 소멸자 및 대입 연산자
👉🏻 항목 6: 컴파일러가 만들어낸 함수가 필요 없으면 확실히 이들의 사용을 금해 버리자
1. 암시적 생성을 막아보자!
// 복사를 하도록 두고 싶지 않은 클래스
class HomeForSale { ... };
HomeForSale h1;
HomeForSale h2;
HomeForSale h3(h1); // 복사하게 두고 싶지 않음!
h1 = h2; // 복사하게 두고 싶지 않음!
저대로 둔다면 컴파일러는 암시적으로 복사 생성자/복사 대입 연산자를 생성할 것이다.
위와 같은 경우에 어떻게 해야할까?
이전 항목 5에서 보았다시피, 자동으로 생성되는 멤버 함수를 private로 두면 해결이 된다.
1.1. private로 선언
class HomeForSale {
public:
...
private:
HomeForSale(const HomeForSale&); // 선언만 존재
HomeForSale& operator=(const HomeForSale&);
};
이처럼 자동으로 생성될 멤버 함수를 먼저 선언하고, 내용을 비우고, private로 두면 컴파일러가 생성하는 것을 막을 수 있다.
이렇게 하면, friend 함수 혹은 직접 호출을 통해 복사하려는 시도를 막을 수 있다.
추가적으로, 선언시 매개변수의 이름은 필수사항이 아니므로, 빼버려도 괜찮다.
이대로 구현한 뒤, 객체를 복사하려한다면 링크하는 시점에서 에러가 날 것이다.
이를 컴파일 시점 에러로 옮기려면 어떻게 해야할까?
1.2. 상속을 이용하자!
class Uncopyable {
protected:
Uncopyable() {}
~Uncopyable() {}
private:
Uncopyable(const Uncopyable);
Uncopyable& operator=(const Uncopyable&);
};
class HomeForSale : private Uncopyable { ... };
상속을 이용하면 컴파일러 시점으로 에러를 옮길수 있으며, 더 간결하게 원하는 의도를 이룰 수 있다.
아래는 이펙티브 C++을 공부하다보면 알게 될 추가적인 내용이다.
1. Uncopyable로부터의 상속은 public일 필요가 없다.
2. Uncopyable의 소멸자는 가상 소멸자가 아니어도 된다.
3. Uncopyable 클래스는 데이터 멤버가 전혀 없어, 공백 기본 클래스 최적화(empty base class optimization) 기법이 먹혀 들어갈 여지가 있다.
🧐 정리
- 컴파일러에서 암시적으로 생성하는 멤버 함수를 막으려면, 미리 private로 선언한 뒤, 구현은 비워두자.
- Uncopyable과 같이 멤버 함수를 막아둔 클래스를 상속시키는 것도 하나의 방법이다.
댓글남기기