ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Effective C++] 6. 컴파일러가 만들어낸 함수가 필요 없으면 이들의 사용을 금해 버리자
    C_C++ 프로그래밍/Effective C++ 2019. 9. 6. 22:51

          로재의 개발 일기      

    컴파일러가 자동으로 생성

    컴파일러는 필요에 따라서 생성자, 복사 생성자, 소멸자를 자동적으로 생성을 하게 됩니다.

    하지만 이를 막고 싶다면 어떻게 해야할까요?


    이번 항목은 다음과 같이 제시하고 있습니다.

    1. 통상적으로 쓰였던 private (friend 접근은 막지 못합니다)

    2. friend까지 막을 수 있는 기반 클래스 작성



      private를 통해서 막아봅시다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    /*
     * Made person: rojae
     * Made date: 2019.09.06
     * --- code description ---
     *  private를 사용하여 자동 복사 생성자 호출을 
     *  막아보자.
     *
     *  HomeForSale의 private에 있는 복사 생성자를 통해서
     *  복사 생성이 금지가 되지만, 이 없이 friend함수를 통해서
     *  복사가 가능해진다.
     *  이 마저도 금지할 수 없을까?
     */
     
    #include<iostream>
     
    class person;
     
      class HomeForSale{
              public:
                      HomeForSale();
                      HomeForSale(const int& cost) : money(cost)
                      {   };
                      friend person;        // friend 클래스를 선언하여 외부에서 private로 접속이 가능하게 된다
                      // friend로 복사 생성자를 만들었기 때문에 실행이 가능하다
                      friend HomeForSale& HomeForSale(const HomeForSale&);
                      friend void getMoney(HomeForSale& h){
                              std::cout << h.money << '\n';
                      }
              private:
                      // 주석 해제시 private로 선언하였기 때문에 
                      // HomeForSale h3(h1)이 컴파일 오류
                      // HomeForSale(const HomeForSale&);
                      HomeForSale& operator = (const HomeForSale&);
                      int money;
      };
     
      class person{
              public:
                      void getMoney(HomeForSale& ob){
                              std::cout << ob.money << '\n';
                      }
              private:
     
      };
     
    int main(){
            HomeForSale h1(100);
            HomeForSale h2(200);
     
            // 주석을 해제하면 컴파일 오류가 일어난다.
            // HomeForSale에서 private로 복사 생성자를 생성했기 때문에
            HomeForSale h3(h1);
     
            // person p1을 통해서 HomeForSale에 접근이 가능하게 된다
            person p1;
            p1.getMoney(h2);
     
            return 0;
    }
     
    cs


    Class 내부에서 작성된 friend 함수의 접근 막을 수 없었습니다.

    이를 막기 위해서는 기반 클래스 Uncopyable( 통상적인 이름입니다만..) 과 같이

    작성하여 금지가 가능합니다.


      Uncopyable 기반 클래스 작성

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    /*
     * Made person: rojae
     * Made date: 2019.09.06
     * --- code description ---
     * 이번에는 완벽하게 막아보자
     * private만 사용하면 friend를 통한 접근은
     * 막을 수 없었다.
     * friend를 막을 수 있는 방법은 기반 클래스를 작성하여
     * 복사 생성을 금지하는 법이다.
     */
     
    #include<iostream>
     
     
    class person;
     
     
    class Uncopyable {
            protected:
                    // 파생된 객체들에 대해
                    Uncopyable(){}
                    ~Uncopyable(){}
            private:
                    Uncopyable(const Uncopyable&);
                    Uncopyable& operator = (const Uncopyable&);
     
    };
     
      class HomeForSale: private Uncopyable{
              public:
                      HomeForSale();
                      HomeForSale(const int& cost) : money(cost)
                      {   };
                      friend person;        // friend 클래스를 선언하여 외부에서 private로 접속이 가능하게 된다
                      friend HomeForSale& HomeForSale(const HomeForSale&);
              private:
                      // 1차적으로 private에서 복사 생성이 막아진다.
                      // 하지만 막지 않는다면?
                      // friend에서 복사 생성이 실행된다
                      // 하지만 Uncopyable 클래스가 기반 클래스로
                      // 기반 클래스의 private를 통해서 복사 생성이 금지된다 
        //            HomeForSale(const HomeForSale&);
                      HomeForSale& operator = (const HomeForSale&);
                      int money;
      };
     
      class person{
              public:
                      void getMoney(HomeForSale& ob){
                              std::cout << ob.money << '\n';
                      }
              private:
     
      };
     
    int main(){
            HomeForSale h1(100);
            HomeForSale h2(200);
     
            // 주석을 해제하면 컴파일 오류가 일어난다.
            // HomeForSale에서 private로 복사 생성자를 생성했기 때문에
            HomeForSale h3(h1);
     
            // person p1을 통해서 HomeForSale에 접근이 가능하게 된다
            person p1;
            p1.getMoney(h2);
     
            return 0;
    }
     
    cs


    마무리

    이렇게 하면 편할 것 같다!

    ※ 본 글은 개인 포트폴리오 혹은 공부용으로 사용하기 때문에, 무단 복사 유포는 금지하지만, 개인 공부 용도로는 얼마든지 사용하셔도 좋습니다


    반응형
Designed by Tistory.