목차

C++ 복사 생성자

복사 생성자는 객체의 복사가 이루어질 때 호출되는 생성자이다.

아래와 같은 클래스가 있다고 해보자.

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.

즉, 컴파일러 차원에서도 복사 생성자는 반드시 레퍼런스로 넘겨야 한다고 말하고 있다.

그렇다면, 값으로 매개변수로 넘겨주었을 때 어떤 과정을 거치길래 무한 반복에 빠지는 것일까?