본문 바로가기
C++

[C++] 얕은 복사(Shallow copy) VS 깊은 복사(Deep copy)

by 유노brain 2023. 10. 29.
반응형

얕은 복사 (Shallow copy)

얕은 복사의 경우 데이터의 주소를 복사하는 것입니다.

다음 아래 그림을 보면 이해하기 쉽습니다.

 

x = y를 통해 y의 주소값을 x에 넣습니다.

그렇기 때문에 *y의 값이 변하면 마찬가지로 *x의 값이 *y와 같게 변합니다.

 

 

깊은 복사 (Deep copy)

깊은 복사의 경우 데이터 값을 완전히 복사하는 것을 말합니다.

그렇기 때문에 복사된 값과 이전의 값은 완전히 독립적으로 됩니다.

 

 

얕은 복사 예시코드

다음은 얕은 복사에 관한 예시코드입니다.

#include <iostream>
#include <string>
#include <string.h>


class Car{  //class declaration
    public: //members accessible from outside
    Car(char* name){    //default constructor
        name_ = new char[sizeof name];
        strcpy(name_,name);
    }
    void set_name(char* new_name){
        free(name_);
        name_ = new char[sizeof new_name];
        strcpy(name_, new_name);
    }
    Car(const Car& car) : name_(car.name_){} //Copy constructor for shallow copy

    const char* name(){ return name_;}
    private:
    char* name_;
};

int main(){
    Car car1("hyundai");
    Car car2 = car1;
    std::cout << car1.name() <<std::endl; //hyundai
    std::cout << car2.name() <<std::endl; //hyundai

    car1.set_name("BMW");
    std::cout << car1.name() <<std::endl; // BMW
    std::cout << car2.name() <<std::endl; // BMW
    return 1;

}

위의 코드를 실행해 보면

car1과 car2의 이름이 같게 나오게 됩니다.

즉 위에서 Car의 주소값을 복사하면서 위와 같은 결과가 나오게 됩니다.

 

 

깊은 복사 예시코드

다음은 깊은 복사 예시코드입니다.

#include <iostream>
#include <string>
#include <string.h>


class Car{  //class declaration
    public: //members accessible from outside
    Car(char* name){    //default constructor
        name_ = new char[sizeof name];
        strcpy(name_,name);
    }
    void set_name(char* new_name){
        free(name_);
        name_ = new char[sizeof new_name];
        strcpy(name_, new_name);
    }
    Car(const Car& car){
        name_ = new char[sizeof car.name_];
        strcpy(name_,car.name_);
    } //Copy constructor for shallow copy

    const char* name(){ return name_;}
    private:
    char* name_;
};

int main(){
    Car car1("hyundai");
    Car car2 = car1;
    std::cout << car1.name() <<std::endl; //hyundai
    std::cout << car2.name() <<std::endl; //hyundai

    car1.set_name("BMW");
    std::cout << car1.name() <<std::endl; // BMW
    std::cout << car2.name() <<std::endl; // hyundai
    return 1;

}

위 코드를 보면 Car(const Car&car) 부분에서 
따로 name_의 공간을 만드는 것을 확인할 수  있습니다.

즉 같은 주소값을 이용하는 것이 아닌 새로운 주소를 만들었다고 볼 수 있습니다.

그렇기 때문에 아래의 결과를 보면

car1은 "BMW"로 변경이 되지만

car2의 경우 그대로 "hyundai"로 남아있는 것을 확인할 수 있습니다.

 

반응형

댓글