Computer >> 컴퓨터 >  >> 프로그래밍 >> C++

C++에서 배열 멤버는 깊은 복사(Deep Copy)될까?

구조체 대입과 배열 멤버의 복사 방식

C/C++에서는 같은 타입의 구조체(struct) 변수를 다른 변수에 대입할 수 있습니다. 이때 구조체 변수를 대입하면 해당 변수의 모든 멤버가 다른 구조체 변수로 복사됩니다. 그렇다면 구조체 내부에 배열이 포함되어 있을 때는 어떻게 동작할까요?

배열 멤버는 자동으로 깊은 복사된다

여기서 중요한 핵심은 배열 멤버는 얕은 복사(shallow copy)가 아니라, 컴파일러가 자동으로 깊은 복사(deep copy)를 수행한다는 점입니다.

아래 예제 프로그램의 구조체 test는 배열 멤버 str1[20]을 가지고 있습니다. st1을 st2에 대입하면 st2는 배열의 새로운 복사본을 갖게 됩니다. 따라서 이후 st1의 str1 배열 값을 변경하더라도 st2의 배열에는 아무런 영향을 주지 않습니다.

예제 코드

# include <iostream>
# include <string.h>
using namespace std;
struct test{
    char str1[20];
};
int main(){
    struct test st1, st2;
    strcpy(st1.str1, "Tutorial Point");
    st2 = st1;
    st1.str1[0] = 'X';
    st1.str1[1] = 'Y';
    /* 깊은 복사가 이루어졌기 때문에 두 배열은 서로 다른 메모리를 사용 */
    cout<< "st1's str = " << st1.str1 << endl;
    cout<< "st2's str = " << st2.str1 << endl;
    return 0;
}

실행 결과

st1's str = XYtorial Point
st2's str = Tutorial Point

실행 결과를 보면 st1의 첫 두 글자를 'X', 'Y'로 변경했음에도 st2의 문자열은 원래 값인 "Tutorial Point" 그대로 유지되는 것을 확인할 수 있습니다. 이는 대입 시점에 배열 전체가 새로운 메모리 공간에 복사되었기 때문입니다.

결론: 별도의 복사 생성자가 필요 없다

따라서 C++ 클래스에서 배열 멤버를 사용하는 경우에는 별도의 복사 생성자(copy constructor)나 대입 연산자(assignment operator)를 직접 작성할 필요가 없습니다. 기본 동작 자체가 배열에 대해 깊은 복사를 수행하기 때문입니다.

다만 포인터 멤버를 가진 클래스의 경우에는 여전히 얕은 복사 문제가 발생할 수 있으므로, 이 경우에는 복사 생성자와 대입 연산자를 명시적으로 정의해 주는 것이 좋습니다.