Programming Language/C++

[C++] 복사 생성자 오버로딩

lumana 2024. 3. 12. 22:23

복사 생성자 오버로딩


  • 복사 생성자란 객체를 다른 객체로 복사하는 데 사용되는 특별한 생성자
  • 동일한 클래스의 다른 객체로부터 호출되며, 그 결과로 현재 객체가 다른 객체와 동일한 상태로 초기화됨
/* 생략 */
// 복사 !!!생성자!!!의 작동
    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 강의