ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • ch02-2. 암시적(디폴트) 함수가 필요 없으면, 확실히 사용을 금하자.
    effective c++ & c++ 2022. 9. 26. 20:20

    컴파일러가 자동으로 만들어 내는 디폴트 함수의 사용을 막기 위해서는,

    멤버 함수를 private으로 선언해준다. 

     

    멤버 함수를 private으로 선언해 준 경우,

    1. 명시적으로 멤버 함수를 선언해주었기 때문에, 컴파일러는 자동으로 디폴트 함수를 생성하지 않는다.

    2. private으로 선언해주었기 때문에 외부로부터의 호출을 막을 수 있다.

     

    이는 클래스의 멤버 함수 및 friend 함수에서 그 멤버 함수를 호출할 수 있다는 허점이 존재한다.

     

    이 허점을 막기 위해서는 그 멤버 함수의 정의를 제외하는 방법이 있다.

    즉, 멤버 함수의 선언만 존재한다.

    class HomeForSale{
    public:
    ...
    private:
    ...
        HomeForSale(const HomeForSale&); //복사 생성자
        HomeForSale& operator=(const HomeForSale&);
    };

    이 경우에, 멤버 함수 및 friend 함수에서 private으로 선언만 된 복사 생성자 및 대입 연산자 함수를 호출하려 할 때,

    링크 시점에서 에러를 발생시킨다.

    링크 시점에서 에러를 발생시키는 경우보다, 컴파일 시점에서 에러를 발생시킬 수 있는 방법이 존재한다.

    1. HomeForSale의 기본 클래스 생성.

    2. 기본 클래스에서 복사 생성자 및 대입 연산자를 private에 선언.

    -> 기본 클래스에서 private으로 선언해주면 유도 클래스에서도 접근 불가능한 특징을 가지고 있다.

    class Uncopyable{
    protected:
        Uncopyable() {}
        ~Uncopyable() {} // 파생된 클래스에 생성과 소멸 허용.
    private:
        Uncopyable(const Uncopyable&);
        Uncopyable& operator=(const Uncopyable&);
    };
    class HomeForSale : private Uncopyable {
    ...
    };

     

    컴파일러가 생성한 복사 함수는 기본 클래스의 대응 버전을 호출하게 되어있기 때문에,

    HomeForSale를 통해 복사 생성자나 대입 연산자를 호출하는 경우

    컴파일 시점에서 복사 생성자와 대입 연산자 생성을 막게 된다.

     

     

    부스트 라이브러리를 보면, Uncopyable과 같은 기능을 수행하는

    클래스(noncopyable)를 찾을 수 있는데, 이것을 써도 된다. 

     

    ** 부스트 라이브러리 : c++의 필수 라이브러리를 모아놓은 라이브러리 집합.

    다운받아 설치 후, 이용이 가능한 것으로 보인다.

     

    #include <boost/noncopyable.hpp>
    
    class HomeForSale : boost::noncopyable{
    ...
    };

     

    Uncopyable을 상속 받을 때, public일 필요가 없는 이유와,

    Uncopyable의 소멸자가 가상 소멸자가 아니어도 되는 이유는 차후 나오는 내용이니 

    차근차근 알아가보는 것이 좋겠다.ㅎㅎ

Designed by Tistory.