[C++] 복사 생성자(Copy constructor), 얕은 복사(Shallow Copy), 깊은 복사(Deep Copy)
2022. 2. 9. 00:45ㆍLanguages/C++
*<씹어먹는 C++>을 보며 공부하여 정리한 글입니다.
1. 복사 생성자(Copy constructor)
- 객체를 복사하여 생성할 때 호출되는 생성자를 말한다.
- 사용자가 따로 넣지 않을 경우, 컴파일러가 자동적으로 디폴트 복사 생성자를 삽입해준다.
class Monster {
char* name;
int hp;
int damage;
public:
Monster(const Monster& copyMonster); // 복사 생성자
...
};
- 함수 내부에서, 받은 인자의 값을 변경할 일이 없다면 다음과 같이 정의하는 것이 더 안전하다.
Moster(const Monster& copyMonster);
- 즉, 다른 객체의 상수 레퍼런스를 매개변수로 받는다.
- const 이기 때문에 복사 생성자 내부에서 매개변수로 가져온 참조 데이터를 직접 변경하는 것이 불가능하다.
- 즉, 읽어와서 복사하는 것만 가능하기에 실수로 참조 데이터 값을 변경한다는 등의 실수를 줄일 수 있다.
- 복사 생성자는 오직 객체 생성 시에만 호출된다.
Monster monster1;
Monster monster2(monster1); // 복사 생성자 호출
Monster monster3 = monster1; // 역시 복사 생성자 호출
Monster monster4;
monster4 = monster1; // 단순 대입 연산. 복사 생성자 호출 X
얕은 복사(Shallow Copy)
- 값들을 복사하여 새로 생성한 객체에 대입해주는 연산을 의미한다.
- 디폴트 복사 생성자는 얕은 복사 과정을 진행한다.
- 포인터나 참조한 값을 복사하여 대입하면, 소멸자가 실행될 때 중복 delete가 될 수 있기에 문제가 발생한다.
Monster(const Monster& copyMonster) {
hp = copyMonster.hp;
damage = copyMonster.damage;
// name = copyMonster.name; 같은 name을 가리키기 때문에 중복 delete의 위험이 있다.
}
깊은 복사(Deep Copy)
- 얕은 복사를 진행하되, 포인터나 참조한 값은 새로 메모리를 할당하여 복사해주는 것을 말한다.
- 이렇게 할 시, 소멸자에서 각각 다른 메모리를 해제하기 때문에 문제가 발생하지 않는다.
- 위에도 언급했듯이, 디폴트 복사 생성자는 얕은 복사만 하므로 깊은 복사를 하는 생성자는 직접 만들어줘야 한다.
Monster(const Monster& copyMonster) {
hp = copyMonster.hp;
damage = copyMonster.damage;
// 깊은 복사. C-style보다는 string을 추천하지만 예시를 들기 위해...
name = new char[strlen(copyMonster.name) + 1];
strcpy(name, copyMonster.name);
}
728x90
반응형
'Languages > C++' 카테고리의 다른 글
[C++] 참조 리턴 함수 (0) | 2022.02.09 |
---|---|
[C++] 초기화 리스트(Initializer list), static (0) | 2022.02.09 |
[C++] 생성자(Default Constructor) 사용 시 주의사항 (0) | 2022.02.08 |
[C++] C++ 컴파일러에서 함수를 오버로딩(Overloading)하는 과정 (0) | 2022.02.08 |
[C++] 참조자(Reference) (0) | 2022.02.08 |