[Modern C++] Summary of special member function generation

Program Lang./C++ 2019. 9. 20. 10:56

1. special member function이란?

 

아래 6가지 member function에 대해서 컴파일러가 자동생성해주는 것을 말함. (by Scott Meyers)

아래 6가지 모든 함수를 사용자가 생성하지 않으면, 컴파일러가 자동으로 모두 생성해준다. 

하지만 경우에 따라서 사용자가 아래 6가지 함수 중에 하나 이상을 선언하는 경우가 발생할 수 있다.

특히 move는 성능과 직결되는 것으로 move관점에서 핵심만 정리한다.

  • default constructor (기본생성자)
  • copy constructor (복사생성자)
  • copy assignment operator (복사대입연산자)
  • move constructor (이동생성자)
  • move assignment operator (이동대입연산자)
  • destructor (소멸자)

2. move 자동생성 조건

 

move가 자동생성되기 위해서는 아래 세가지 조건이 모두 만족되어야 한다.

  • No copy operations are declared in the class
  • No move operations are declared in the class
  • No destructor is declared in the class.

하지만 위의 세가지 조건을 모두 만족시키기 어려운 상황이 크게 두 가지 존재한다.

  • class내에 raw pointer 기반 resource 관리 시
    • raw pointer는 모두 삭제하고, STL container 기반으로 코드 수정해야 한다.
  • 클래스가 상속관계에 있을 경우
    • 해당 경우에 대해서 아래에서 상세하게 살펴본다.

3. move 자동생성이 안되는 경우 - class inherit condition

 

class 상속관계에서는 상위(부모) class의 desctructor는 virtual로 사용자가 선언해야 한다.

이런 제약 사항이 move의 자동생성 조건을 만족시킬 수 없어서 move가 자동생성되지 않는다. 

이로 인해 class 설계자가 고려해야 할 사항들에 대해서 정리하였다.

  1. class 설계자는 move operation들을 생성해야한다.
    • 사용자 desctructor의 생성은 move operation이 자동생성되지 않기 때문
  2. class 설계자는 copy operation들을 생성해야 한다
    • 사용자가 move operation들을 생성하면, copy operation들은 제거되거나 자동생성되지 않기 때문
    • copy operation 자동생성 조건은 따로 정리하지 않았지만, 이 정도만 기억하면 될 것으로 보인다.
  3. class 설계자는 default 생성자를 사용해야 한다면, 생성해야 한다.
    • 사용자가 move operation를 생성하면 모든 생성자가 제거되거나 자동생성되지 않기 때문

결론적으로 class가 상속관계에 있는 경우, 6가지 special member function들에 대해서 잘 설계를 해야한다.

 

만약 단순히 virtual 때문에 destructor를 사용자가 선언해야하는 조건이라면, 컴파일러가 자동생성한 것과 동일하게 생성해 달라고 명시하면 된다.

만약 사용자가 컴파일러가 자동생성하는 코드와 다르다면 모두 사용자가 생성해줘야 한다.

 

 

4. template 사용의 경우

 

Effective Modern C++ 책에서는 17장 마지막에 애매하게 설명하고 정리하였다.

아래 코드 테스트를 통해서, template라고 해서 특별히 위의 생성 규칙과 다른 점은 없었다.

move에 대해서 위의 규칙을 잘 이해하고 있다면, template에서도 동일하게 적용된다. 

 

5. 정리

 

special member function은 컴파일러가 자동생성하는 함수들이다.

자동생성되는 함수들은 클래스의 public 영역에 inline으로 생성된다.

special member function들 중에 사용자 생성으로 자동생성되지 않는 규칙이 존재한다.

다른 규칙은 외우지 않아도 빌드 중에 모두 수정할 수 있다.

하지만 move의 특성상 move는 copy로 대체가 가능하여 move의 자동생성조건을

명확히 이해하지 않는다면, 원하지 않게 copy로 동작하여 성능저하의 문제를 겪을 수 있다.

이런 관점에서 move 관점에서 상세하게 살펴보았다.

: