KoreanFoodie's Study

Effective C++ | 항목 6 : 컴파일러가 만들어낸 함수가 필요 없으면 확실히 이들의 사용을 금해 버리자 본문

Tutorials/C++ : Advanced

Effective C++ | 항목 6 : 컴파일러가 만들어낸 함수가 필요 없으면 확실히 이들의 사용을 금해 버리자

GoldGiver 2022. 10. 25. 16:04

C++ 프로그래머의 필독서이자 바이블인, 스콧 마이어스의 Modern Effective C++ 를 읽고 기억할 내용을 요약하고 있습니다. 꼭 읽어보시길 추천드립니다!

항목 6 : 컴파일러가 만들어낸 함수가 필요 없으면 확실히 이들의 사용을 금해 버리자

핵심 :

컴파일러에서 자동으로 제공하는 기능을 허용치 않으려면, 대응되는 멤버 함수를 private 으로 선언한 후에 구현은 하지 않은 채로 두자. Uncopyable 과 비슷한 기본 클래스를 쓰는 것도 한 방법이다.


우리가 부동산을 판매하는 프로그램을 만들게 되었는데, 각 자산은 세상에서 하나밖에 없다는 것을 적용해 달라고 요청했다고 가정해 보자. 즉, 다음과 같은 코드는 컴파일이 되면 안된다는 뜻이다!

class HomeForSale {...};

...

HomeForSale h1;
HomeForSale h2;

// h1을 복사하려고 함 -> 컴파일되면 안됨!
HomeForSale h3(h1);

// h2 를 복사하려고 함 -> 컴파일되면 안됨!
h1 = h2;

컴파일러는 기본 복사 생성자와 기본 대입 연산자를 public 으로 만들어 버려서 이런 문제가 발생한다! 이 문제를 어떻게 해결할까?
먼저, 기본 복사 생성자 및 대입 연산자를 private 으로 선언한다. 하지만 해당 클래스의 friend 함수는 private 함수를 호출할 수 있으므로, 복사 생성자 및 대입 연산자를 선언만 하고, 구현을 하지 않음으로써 링커 에러를 일부러 만들 수 있다!

class HomeForSale
{
  public:
    ...
  private:
    ...
    // 선언만 달랑 존재한다
    HomeForSale(const HomeForSale&);
    HomeForSale& operator=(const HomeForSale&);
};

추가로, 에러 발생 시점을 링크 시점에서 컴파일 시점으로 옮길 수도 있다. 복사 생성자와 복사 대입 연산자를 private 으로 선언한 부모 클래스에서 HomeForSale 을 파생시키는 방법이다!

class UnCopyable
{
  protected:
    // 생성과 소멸은 허용한다
    UnCopyable() {}
    ~UnCopyable() {}
  private:
    // 하지만 복사는 방지한다
    UnCopyable(const UnCopyable&);
    UnCopyable& operator=(const UnCopyable&);
};

// 복사 생성자와 복사 대입 생성자가 선언되지 않는다
class HomeForSale : private UnCopyable { ... };
Comments