C++ 깊은 복사 함수 (copy)

Seongcheol Jeon·2024년 11월 17일
0

CPP

목록 보기
21/47
post-thumbnail

프로그래밍에서 복사는 두 가지 종류가 있다. 하나는 얕은 복사 (shallow copy), 다른 하나는 깊은 복사 (deep copy)이다.

  • 얕은 복사
    • 주소값을 복사
  • 깊은 복사
    • 실제 값을 새로운 메모리 공간에 복사

얕은 복사는 복사 대상이 주소값이므로 참조하는 값이 서로 같다. 따라서 원본 값이 바뀌면 복사한 값도 바뀐 값을 참조한다.

반면에 깊은 복사는 서로 다른 독립적인 메모리에 실제 값까지 복사하는 것을 의미한다. 따라서 깊은 복사에서는 원본 값이 바뀌어도 복사한 값에는 영향이 없다.

깊은 복사를 반복문으로 직접 구현하면 객체에 포함된 모든 원소를 하나하나 복사하므로 코드도 길고, 양에 따라 오래 걸리 수도 있다. 표준 라이브러리에서는 이를 보완하고자 깊은 복사 함수 copy를 제공한다.

copy 함수의 원형은 다음과 같다. _First부터 _Last전 까지의 모든 원소를 _Dest부터 시작하는 곳에 복사한다.

template <class _InIt, class _OutIt>
_CONSTEXPR20 _OutIt copy(_InIt _First, _InIt _Last, _OutIt _Dest)

다음 코드는 copy 함수를 활용한 예이다.

#include <iostream>
#include <vector>
#include <algorithm>
#include <string>


using namespace std;


struct Person {
    string name;
    int age;
    float height;
    float weight;
};


void print_person_all(vector<Person>& people) {
    for (vector<Person>::iterator it = people.begin(); it != people.end(); it++) {
        cout << "Name: " << it->name << endl;
        cout << "Age: " << it->age << endl;
        cout << "Height: " << it->height << endl;
        cout << "Weight: " << it->weight << endl;
        cout << endl;
    }
}


int main()
{
    Person p[5] = {
        {"Alice", 20, 160.0, 50.0},
        {"Bob", 25, 172.0, 62.0},
        {"Charlie", 30, 183.0, 82.0},
        {"David", 35, 191.0, 90.0},
        {"Eve", 40, 179.0, 85.0}
    };

    vector<Person> from_vector;

    from_vector.push_back(p[0]);
    from_vector.push_back(p[1]);
    from_vector.push_back(p[2]);
    from_vector.push_back(p[3]);
    from_vector.push_back(p[4]);

    cout << "----- from_vector -----" << endl;
    print_person_all(from_vector);
    cout << endl;

    // to_vector에 from_vector의 원소를 "깊은 복사" 수행
    vector<Person> to_vector;
    copy(from_vector.begin(), from_vector.end(), back_inserter(to_vector));

    // 복사 후 to_vector 출력
    cout << "----- to_vector -----" << endl;
    print_person_all(to_vector);
    cout << endl;

    // from_vector의 첫 번째 원소 수정
    from_vector[0].name = "Alice2";
    from_vector[0].age = 21;
    from_vector[0].height = 161.0;
    from_vector[0].weight = 51.0;

    // 수정 후 from_vector 출력
    cout << "----- from_vector -----" << endl;
    print_person_all(from_vector);
    cout << endl;

    // to_vector 출력
    cout << "----- to_vector -----" << endl;
    print_person_all(to_vector);
    cout << endl;

    return 0;
}

실행 결과

----- from_vector -----
Name: Alice
Age: 20
Height: 160
Weight: 50

Name: Bob
Age: 25
Height: 172
Weight: 62

Name: Charlie
Age: 30
Height: 183
Weight: 82

Name: David
Age: 35
Height: 191
Weight: 90

Name: Eve
Age: 40
Height: 179
Weight: 85


----- to_vector -----
Name: Alice
Age: 20
Height: 160
Weight: 50

Name: Bob
Age: 25
Height: 172
Weight: 62

Name: Charlie
Age: 30
Height: 183
Weight: 82

Name: David
Age: 35
Height: 191
Weight: 90

Name: Eve
Age: 40
Height: 179
Weight: 85


----- from_vector -----
Name: Alice2
Age: 21
Height: 161
Weight: 51

Name: Bob
Age: 25
Height: 172
Weight: 62

Name: Charlie
Age: 30
Height: 183
Weight: 82

Name: David
Age: 35
Height: 191
Weight: 90

Name: Eve
Age: 40
Height: 179
Weight: 85


----- to_vector -----
Name: Alice
Age: 20
Height: 160
Weight: 50

Name: Bob
Age: 25
Height: 172
Weight: 62

Name: Charlie
Age: 30
Height: 183
Weight: 82

Name: David
Age: 35
Height: 191
Weight: 90

Name: Eve
Age: 40
Height: 179
Weight: 85

copy 함수가 깊은 복사를 하는지 직접 확인하고자 이름을 비롯해 여러 원소를 가진 Person 구조체의 객체들을 벡터 컨테이너에 저장했다.

실행 결과에서 to_vector로 표시한 부분을 보면 Person 구조체의 모든 원소가 완전히 복사된 것을 확인할 수 있다. 또한 to_vector에 복사한 후 from_vector의 첫 번째 값을 변경해도 to_vector에 저장된 원소에는 전혀 영향이 없음을 확인할 수 있다. 즉, from_vector와 독립적으로 깊은 복사가 수행된 것이다.

이처럼 여러 개의 원소를 깊게 복사해야 한다면 표준 라이브러리의 copy 함수를 적극 활용하자. 코드가 간결해질 뿐만 아니라 성능까지 확보할 수 있다.

0개의 댓글