목차
복사 생성자는 객체의 복사가 이루어질 때 호출되는 생성자이다.
아래와 같은 클래스가 있다고 해보자.
class Rectangle {
private:
int width;
int height;
public:
Rectangle(); // 기본 생성자
Rectangle(const Rectangle& src); // 복사 생성자
Rectangle& operator=(const Rectangle& src); // 복사 대입 연산자
~Rectangle(); // 소멸자
}
그리고 복사 생성자는 보통 아래와 같이 복사 대입 연산자를 이용해서 구현한다.
// 복사 생성자
Rectangle::Rectangle(const Rectangle& src) {
*this = rhs; // 복사 대입 연산자 호출
}
// 복사 대입 연산자
Rectangle& Rectangle::operator=(const Rectangle& rhs) {
if (this != &rhs) {
this->width = rhs.width;
this->height = rhs.height;
}
return (*this);
}
하지만 왜 복사 생성자의 매개변수는 꼭 레퍼런스(&
) 자료형으로 받아야 하는 걸까?
왜 아래와 같이 값으로 받으면 안되는 걸까?
// 매개변수를 레퍼런스가 아닌 값으로 받음
Rectangle(const Rectangle src) {
*this = rhs; // 복사 대입 연산자 호출
}
결론부터 말하면 복사 생성자의 매개변수를 값으로 받으면 무한 반복에 빠지기 때문이다.
아래와 같이 코드가 있다고 해보자.
// copy.cpp
class Rectangle {
private:
int width;
int height;
public:
Rectangle(int width, int height);
Rectangle(const Rectangle src);
};
Rectangle::Rectangle(int width, int height) {
this->width = width;
this->height = height;
}
Rectangle::Rectangle(const Rectangle src) {
*this = src;
}
int main() {
Rectangle r1(10, 20);
Rectangle r2(r1);
return 0;
}
MacOS 환경에서 c++ 컴파일러로 컴파일을 시도하면 아래와 같은 에러가 표시된다.
copy.cpp:7:29: error: copy constructor must pass its first argument by reference
Rectangle(const Rectangle src);
^
const &
copy.cpp:15:38: error: copy constructor must pass its first argument by reference
Rectangle::Rectangle(const Rectangle src) {
^
const &
2 errors generated.
즉, 컴파일러 차원에서도 복사 생성자는 반드시 레퍼런스로 넘겨야 한다고 말하고 있다.
그렇다면, 값으로 매개변수로 넘겨주었을 때 어떤 과정을 거치길래 무한 반복에 빠지는 것일까?