C++에서 복사 생성자는 기존 객체를 기반으로 새로운 객체를 생성할 때 사용되는 특별한 생성자입니다. 복사 생성자는 객체의 속성을 복사하여 새로운 객체를 초기화하는 데 중요한 역할을 합니다. 이 글에서는 복사 생성자의 개념, 사용법, 깊은 복사와 얕은 복사의 차이, 그리고 주의사항에 대해 자세히 살펴보겠습니다.
1. 복사 생성자란?
복사 생성자는 클래스의 인스턴스가 다른 인스턴스를 기반으로 생성될 때 호출되는 생성자입니다. 복사 생성자는 다음과 같은 형식을 가집니다.
ClassName(const ClassName &obj);
위의 형식에서 obj
는 복사할 객체를 나타내며, 이 객체의 속성이 새로운 객체에 복사됩니다.
1.1 복사 생성자의 기본 예제
다음은 복사 생성자를 사용하는 간단한 예제입니다.
#include <iostream>
using namespace std;
class Person {
public:
string name;
int age;
// 기본 생성자
Person(string n, int a) : name(n), age(a) {}
// 복사 생성자
Person(const Person &p) {
name = p.name;
age = p.age;
}
void introduce() {
cout << "안녕하세요, 제 이름은 " << name << "이고, 나이는 " << age << "세입니다." << endl;
}
};
int main() {
Person person1("Alice", 30); // 기본 생성자 호출
Person person2 = person1; // 복사 생성자 호출
person2.introduce(); // person2의 정보 출력
return 0;
}
위의 코드에서 person2
는 person1
을 기반으로 생성되며, 복사 생성자가 호출되어 name
과 age
속성이 복사됩니다.
2. 깊은 복사와 얕은 복사
복사 생성자는 깊은 복사와 얕은 복사를 구현할 수 있습니다. 이 두 개념은 객체가 소유하는 자원의 복사 방식에 따라 다릅니다.
2.1 얕은 복사
얕은 복사는 객체의 모든 데이터 멤버를 단순히 복사하는 방식입니다. 기본적으로 C++에서 제공하는 복사 생성자는 얕은 복사를 수행합니다. 이 경우, 포인터가 가리키는 메모리 주소만 복사되므로, 두 객체가 동일한 메모리를 참조하게 됩니다. 이는 메모리 누수나 이중 해제를 초래할 수 있습니다.
class Shallow {
public:
int *data;
// 생성자
Shallow(int value) {
data = new int(value);
}
// 얕은 복사 생성자
Shallow(const Shallow &source) : data(source.data) {}
~Shallow() {
delete data; // 메모리 해제
}
};
위의 코드에서 Shallow
클래스의 복사 생성자는 얕은 복사를 수행하므로, 두 객체가 동일한 data
포인터를 공유하게 됩니다.
2.2 깊은 복사
깊은 복사는 객체가 소유하는 자원을 완전히 복사하는 방식입니다. 즉, 포인터가 가리키는 메모리의 내용을 새로 할당하여 복사합니다. 이를 통해 두 객체가 서로 독립적으로 존재할 수 있습니다.
class Deep {
public:
int *data;
// 생성자
Deep(int value) {
data = new int(value);
}
// 깊은 복사 생성자
Deep(const Deep &source) {
data = new int(*source.data); // 새로운 메모리 할당
}
~Deep() {
delete data; // 메모리 해제
}
};
위의 코드에서 Deep
클래스의 복사 생성자는 깊은 복사를 수행하므로, 각 객체가 독립적인 메모리 공간을 가집니다.
3. 복사 생성자의 중요성
복사 생성자는 객체의 복사 시 데이터의 일관성을 유지하는 데 필수적입니다. 특히 동적 메모리를 사용하는 클래스에서는 깊은 복사를 구현하여 메모리 누수와 이중 해제를 방지해야 합니다. 복사 생성자를 적절히 구현하지 않으면 프로그램의 안정성이 저하될 수 있습니다.
4. 결론
복사 생성자는 C++에서 객체 복사의 중요한 메커니즘으로, 객체의 속성을 안전하게 복사하는 데 필수적입니다. 깊은 복사와 얕은 복사의 개념을 이해하고, 적절한 복사 생성자를 구현함으로써 메모리 관리와 데이터 일관성을 유지할 수 있습니다. 이러한 이해는 복잡한 객체를 다루는 프로그램에서 특히 중요하며, 다음 포스팅에서는 C++의 묵시적 변환에 대해 더 깊이 다루어 보겠습니다.
'C++ 프로그래밍' 카테고리의 다른 글
C++의 임시 객체와 이동 시맨틱: 효율적인 자원 관리 (0) | 2025.02.08 |
---|---|
C++의 묵시적 변환: 타입 변환의 자동화 (0) | 2025.02.08 |
C++의 정적 멤버: 클래스의 공유 데이터와 메서드 (0) | 2025.02.08 |
C++의 메서드: 객체의 행동을 정의하는 요소 (0) | 2025.02.08 |
C++의 생성자와 소멸자: 객체의 생명주기 관리 (0) | 2025.02.08 |
댓글