반응형
C++에서 **복사 생성자(Copy Constructor)**는 객체가 같은 클래스의 다른 객체로부터 복사되어 초기화될 때 호출됩니다. 주로 다음 상황에서 호출됩니다:
- 객체가 복사로 초기화될 때.
- 객체가 함수에 값으로 전달될 때.
- 함수에서 객체를 값으로 반환할 때.
복사 생성자의 기본 형태
ClassName(const ClassName& other); |
const는 복사 생성자가 원본 객체를 수정하지 않도록 보장합니다.
예제
아래는 복사 생성자를 정의하고 사용하는 간단한 예제입니다.
#include <iostream>
#include <cstring>
class MyClass {
private:
char* name; // 동적으로 관리되는 문자열
public:
// 기본 생성자
MyClass(const char* inputName) {
name = new char[strlen(inputName) + 1];
strcpy(name, inputName);
std::cout << "Constructor called for: " << name << std::endl;
}
// 복사 생성자
MyClass(const MyClass& other) {
name = new char[strlen(other.name) + 1]; // 깊은 복사
strcpy(name, other.name);
std::cout << "Copy Constructor called for: " << name << std::endl;
}
// 소멸자
~MyClass() {
delete[] name;
std::cout << "Destructor called for: " << name << std::endl;
}
// 이름 출력 함수
void printName() const {
std::cout << "Name: " << name << std::endl;
}
};
int main() {
MyClass obj1("Original"); // 기본 생성자 호출
MyClass obj2 = obj1; // 복사 생성자 호출 (obj2는 obj1의 복사본)
obj1.printName(); // obj1 출력
obj2.printName(); // obj2 출력
return 0; // 소멸자 호출
}
Constructor called for: Original
Copy Constructor called for: Original
Name: Original
Name: Original
Destructor called for: Original
Destructor called for: Original
복사 생성자 없이 사용하는 경우
만약 복사 생성자를 정의하지 않으면 컴파일러는 기본 복사 생성자를 제공합니다. 그러나 기본 복사 생성자는 **얕은 복사(Shallow Copy)**를 수행합니다. 얕은 복사는 포인터의 값을 복사하므로, 두 객체가 같은 메모리 주소를 참조하게 됩니다. 이로 인해 소멸자에서 동일한 메모리를 두 번 해제하려고 할 수 있습니다(이중 해제 문제).
깊은 복사와 얕은 복사
- 얕은 복사(Shallow Copy): 포인터나 동적 메모리 같은 복합 객체의 주소만 복사합니다.
- 깊은 복사(Deep Copy): 실제 데이터를 새롭게 복사하여 각 객체가 독립적인 메모리를 가집니다.
복사 생성자의 필요성
- 동적 메모리를 사용하는 클래스는 반드시 복사 생성자를 정의하여 깊은 복사를 구현해야 합니다.
- 현대 C++에서는 복사 생성자 대신 Move Constructor와 스마트 포인터를 사용하는 것이 권장됩니다.
반응형
'C_C++' 카테고리의 다른 글
C++, <vector> 템플릿 이용하기 (0) | 2024.11.19 |
---|---|
C++, 클래스 템플릿 class template (0) | 2024.11.18 |
C++, 클래스 생성자에서 동적메모리 사용하는 예 (0) | 2024.11.16 |
C++, 단항연산자 오버로딩 (전위 후위 연산자) (0) | 2024.11.15 |
C++, 프렌드 함수로 연산자 오버로딩 만들기 (0) | 2024.11.14 |