블로그

C++ 깊은 복사 , 얕은 복사 그리고 복사 생성자에 대하여 본문

C++

C++ 깊은 복사 , 얕은 복사 그리고 복사 생성자에 대하여

confielder 2021. 10. 4. 22:31

얕은 복사

얕은 복사는 객체와 객체 간의 복사에서 일어나는 현상으로, 디폴트 복사 생성자에서 멤버 대 멤버의 복사를 진행하여 생긴다.

 

얕은 복사는 힙의 메모리 공간을 참조할 때 문제가 생기는데,

 

Class A {

private:

char *name;

public:

 

A(char *myName) {

int len = strlen(myName) + 1;

name = new char [len];

strcpy(name, myName);

}

~A(){

delete [] name;

}

}; 

 

int main(){

A a("lee);

A b;

 

b=a;

}

 

이런 식의 코드가 있다면 b는 a를 단순히 복사하기 때문에 a 가 가리키고 있는 동적 할당된 변수를 b도 똑같이 가리키고 있는 것이다.

 

이렇게 되면 메모리상에서 a와 b 가 같은 변수의 주소 값을 가리키고 있기 때문에 동적 할당을 delete 할 때 b 객체가 먼저 delete 되면, a 객체가 delete 할 메모리가 사라지는 것이다.

 

따라서 이러한 현상을 방지하려면, 깊은 복사를 위한 복사 생성자를 정의해야 한다.

 

깊은 복사

깊은 복사는 멤버뿐만 아니라 포인터가 가리키고 있는 대상까지 깊게 복사한다는 의미를 가지고 있다.

 

깊은 복사를 위한 복사생성자를 만들면 깊은복사를 할 수 있다.

 

A(A &ref){

name = new char [strlen(ref.name )+ 1];

strcpy(name, ref.name);

}

 

이런 식의 생성자를 따로 만들어서 깊은 복사를 한다.

 

이러면 멤버 간의 복사가 일어날 때 복사 생성자가 호출되어 좌변에 있는 객체가 따로 동적 할당을 하기 때문에 앞서 설명한 문제점이 해결된다.

 

 

복사 생성자가 호출되는 경우

복사 생성자는 총 3가지 경우에 호출이 된다.

 

1. 기존에 생성된 객체를 이용하여 새로운 객체를 초기화하는 경우

2.call by value 방식의 함수 호출 과정에서 객체를 인자로 전달하는 경우

3. 객체를 반한 하되, 참조형으로 반환하지 않는 경우.

 

여기서 세 가지 경우의 공통점으로는 객체가 생성과 동시에 초기화가 된다는 점이다.

 

1번의 경우는 앞서 설명한 경우이다.

ex) Person a(3,2)

Person b = a;

 

이때 b가 a를 복사하며 복사 생성자가 호출된다.

 

2번의 경우에는 이러한 경우이다

ex)

class Person {

public:

 

Person ShowMyName(Person a){

a.age = 0;

}

};

 

int main(){

Person a

a.ShowMyName(a);

}

이런 식의 코드에서 ShowMyName 함수의 객체 a 인자가 클래스에서 선언된 매개변수에 복사되면서 복사 생성자가 호출된다.

 

이럴 때 복사생성자가 호출되는 객체는 매개변수 a이다.

 

3번의 경우에는 

 

Person ShowMyName(Person a){

 

return a;

}

 

이러한 경우로, 객체를 리턴할 때 또한 메모리 공간을 할당하고 초기화되기 때문에 복사 생성자가 호출된다.

 

리턴할 때 생기는 객체를 임시 객체라고 부르며, 이 임시 객체는 매개변수에 의해 복사되어 복사 생성자가 호출되는 방식이다.

 

ex)

a(return 임시 객체) = a(매개변수 객체) 

 

이렇게 깊은 복사, 얕은 복사 그리고 복사 생성자 까지 알아보았다.

 

정리하자면 얕은 복사는 멤버 대 멤버가 단순히 복사되는 형태이지만,  깊은 복사는 객체와 객체의 복사에서 좌변의 객체에게 독립적인 동적 할당을 실행하여 한 객체가 두 개의 변수 혹은 함수를 가리키게 하지 않는 것이다.

 

 

'C++' 카테고리의 다른 글

C++ std::vector 에 대해  (0) 2021.12.26
C++ "Inline"함수란  (0) 2021.12.23
C++ 에서 정적바인딩, 동적바인딩 이란?  (0) 2021.12.09
C++ "Static" 에 대하여  (0) 2021.09.29
C++ "new" 키워드에 대하여  (0) 2021.09.20