C++ 복사 생성자
1. 개요
1.1 문서 개요
이 문서는 C++에서의 복사 생성자(Copy Constructor)에 대해 설명합니다. 복사 생성자는 객체를 다른 객체로 초기화할 때 호출되며, 클래스의 메모리 복사 동작을 제어하는 중요한 구성 요소입니다. 객체 복사 과정에서 얕은 복사와 깊은 복사의 차이를 제어하는 핵심 구조로 활용됩니다.
2. 내용
2.1 복사 생성자의 정의와 역할
2.1.1 복사 생성자의 기본 구조
복사 생성자는 동일한 클래스 타입의 참조를 매개변수로 받는 생성자입니다.
class MyClass {
public:
MyClass(const MyClass& other); // 복사 생성자 선언
};
컴파일러는 사용자가 정의하지 않아도 기본 복사 생성자를 자동으로 제공합니다. 그러나 사용자 정의 복사 생성자는 포인터 기반 리소스를 다룰 때 필수적입니다.
2.1.2 복사 생성자의 호출 시점
복사 생성자는 다음과 같은 경우에 호출됩니다:
- 객체가 다른 객체로 초기화될 때
- 함수에 객체를 값으로 전달할 때
- 함수에서 객체를 값으로 반환할 때
예시:
MyClass a;
MyClass b = a; // 복사 생성자 호출
2.2 사용자 정의 복사 생성자 구현
2.2.1 얕은 복사 문제
얕은 복사는 포인터를 단순 복사하여 두 객체가 같은 메모리 영역을 가리키게 합니다. 이로 인해 double delete 문제가 발생할 수 있습니다.
class Shallow {
int* data;
public:
Shallow(int val) { data = new int(val); }
~Shallow() { delete data; }
Shallow(const Shallow& other) : data(other.data) {} // 얕은 복사
};
2.2.2 깊은 복사 방식
깊은 복사는 별도의 메모리 공간을 새로 할당하여 데이터를 복사합니다.
class Deep {
int* data;
public:
Deep(int val) { data = new int(val); }
~Deep() { delete data; }
Deep(const Deep& other) {
data = new int(*(other.data));
}
};
2.3 Rule of Three 관련성
복사 생성자는 소멸자, 대입 연산자 오버로딩과 함께 관리되는 Rule of Three의 일부입니다. 포인터나 리소스를 직접 다루는 경우 이 세 가지를 함께 정의하는 것이 안정성을 보장합니다.
3. 마무리
C++ 복사 생성자는 객체 복사 시 동작을 제어하는 중요한 도구입니다. 특히 동적 메모리를 다루는 클래스에서는 얕은 복사의 위험을 방지하기 위해 사용자 정의 복사 생성자를 구현해야 하며, 이는 Rule of Three의 일환으로 고려되어야 합니다.