복사 생성자 오버로딩
- 복사 생성자란 객체를 다른 객체로 복사하는 데 사용되는 특별한 생성자
- 동일한 클래스의 다른 객체로부터 호출되며, 그 결과로 현재 객체가 다른 객체와 동일한 상태로 초기화됨
/* 생략 */
// 복사 !!!생성자!!!의 작동
String(const String &rhs) { // String s2(s1); 사용시 발생하는 일.
// const String rhs 로 선언하면 안된다(무한 루프에 빠짐)
cout << "String(String &rhs) 생성자 호출" << '\n';
// strData = rhs.strData; // 얕은 복사로 인해 메모리 해제 2번
strData = new char[rhs.len + 1]; // len의 크기를 모르기 때문에 len + 1 로 문자열 크기를 정할 수 없다. rhs.len을 사용하자.
cout << "strData할당: " << (void *)strData << endl;
strcpy(strData, rhs.strData); // 깊은 복사
len = rhs.len; // 깊은 복사
}
/* 생략 */
int main() {
String s1("안녕");
String s2(s1); // 복사 생성자
// 기본적으로 소멸은 선언의 역순
cout << s1.GetStrData() << '\n';
cout << s2.GetStrData() << '\n';
}
- String(const String &rhs) 에서 rhs가 아닌 &rhs를 사용해야 함
- 레퍼런스로 선언하지 않으면 매개변수가 전달되는 과정에서 rhs(전달된 매개변수) 가 일어남
- 이는 다시 복사 생성자를 호출하므로, 무한 루프에 빠지게 됨
- 따라서 매개변수를 참조로 받도록 선언해서 복사 생성자가 호출되지 않도록 해야 함
복사 생성자가 작동할 때 매개 변수의 값이 생성자로 전달되는 과정에서 복사 생성자가 또 동작하고, 이 복사 생성자에서 매개 변수를 전달하는 과정에서 복사 생성자가 동작하고.... 무한 루프에 빠지게 되는 것이다. 따라서 레퍼런스로 선언하여 매개변수가 전달될 때 얕은 복사가 이루어질 수 있도록 해야 하는 것이다.
- strData = rhs.strData; 로 복사하게 되면 얕은 복사가 일어나 메모리를 해제하는 과정에서 오류가 발생함
- strData에 rhs.len + 1의 길이를 갖는 새로운 char형 배열을 선언한 후 strcpy로 깊은 복사
- 만약 String s3; 로 선언하고 s3 = s1;을 한다면?? --> 대입 연산자 오버로딩을 살펴보자(다음 챕터)
참조) 두들낙서 C/CPP 강의
'Programming Language > C++' 카테고리의 다른 글
[C++] 이동 시맨틱(Move Semantics): 이동 생성자, 이동 대입 연산자 (0) | 2024.06.27 |
---|---|
[C++] 대입 연산자 오버로딩 (0) | 2024.03.12 |
[C++] 깊은 복사와 얕은 복사(Deep Copy, Shallow Copy) (0) | 2024.03.12 |
[C++] 동적할당 (0) | 2024.02.04 |
[C++] 연산자 오버로딩 (0) | 2024.02.04 |