Effective C++ 정리
05. 컴파일러가 자동으로 생성하는 함수
cks5730
2019. 12. 20. 00:17
기본 생성자 / 기본 소멸자 / 복사 생성자 / 복사 대입 연산자
class Empty
{
// 정의하지 않았을때 자동으로 생성되는 함수들
// public, inline 함수로 생성된다.
public:
Empty() {...}
Empty(const Empty& rhs) {...}
~Empty() {...}
Empty& operator = (const Empty& rhs) {...}
};
기본 생성자와 기본 소멸자는 직접 정의하지 않았을때
컴파일러가 public, Inline 함수로 자동으로 생성해줍니다.
그러나 인자있는 생성자를 직접 정의했을 경우, 컴파일러는 기본 생성자를 생성하지 않습니다.
복사 생성자와 복사 대입 연산자도 컴파일러에 의해 자동으로 생성됩니다.
(C++11에서 이동 생성자, 이동 대입 연산자가 추가되었습니다)
그러나 복사 대입 연산자에서 주의사항이 있습니다.
함수의 접근 지정자가 private이거나 참조자 멤버 또는 const 멤버가 존재할 경우
컴파일러는 복사 대입 연산자를 자동으로 생성하지 않습니다.
// Dog.h //
template <typename T>
class Dog
{
public:
Dog(std::string& name, const T& value) {...}
// 아래와 같은 복사 대입 연산자는 없다고 가정한다.
// Empty& operator = (const Empty& rhs) {...}
private:
std::string& m_strName; // 참조자 멤버 객체
const T m_Value; // const 멤버 객체
};
#include "Dog.h"
int main()
{
std::string DogName1("John");
std::string DogName2("Peter");
Dog<int> dog1(DogName1, 1);
Dog<int> dog2(DogName2, 2);
// Dog1 = Dog2; // error !! 컴파일 거부 !!
return 0;
}
참조자 멤버는 한 번 초기화 되면 다른 객체를 참조할 수 없습니다.
dog1의 m_strName은 dog2의 m_starName을 다시 가리킬 수 없게 되죠.
const 멤버도 한 번 지정되면 데이터를 변경할 수 없습니다.
복사 대입 연산자 함수를 오버로딩을 해야겠군요.
상속 관계에서도... 기본 클래스에서 private으로 선언된 복사 대입 연산자가 있을 경우
파생 클래스에서 복사 대입 연산자를 호출할 수 없습니다.
파생 클래스에서 복사 대입 연산자를 호출할 권한이 없기 때문입니다.
그래서 파생 클래스에 컴파일러가 복사 대입 연산자를 자동으로 생성해주지 않습니다.