지난 포스팅에서 이어서 설명한다고 했던 깊은 복사에 대해 다루려고 한다.
깊은 복사에 대해 이야기하면
필연적으로 얕은 복사와 함께 이야기하는데,
얕은 복사와 깊은 복사를 비교해 보며 알아보자.
정의
정의적인 부분부터 살펴보자.
얕은 복사
복사하려는 원본에 대한 새로운 객체(복사본)를 생성하는데,
이 객체는 원본 객체를 참조한다.
즉, 생성된 복사본은 원본 객체가 가리키는 주소와 같은 곳을 가리키게 된다.
그렇기 때문에 복사본은 원본 객체에 종속적이다.
이는 주소에 의한 참조랑 비슷한 의미로 생각해도 된다.
깊은 복사
얕은 복사와 같이 원본에 대한 복사본을 생성하는데,
인스턴스화할 수 있는 모든 요소
(내부의 클래스 변수, 메서드, 인스턴스 값 등)를 모조리 복사한다.
그렇게 하여 원본 객체로부터 완전히 독립적인 객체를 생성한다.
즉, 생성된 복사본은 원본 객체에 종속적이지 않고 독립적이다.
코드로 알아보기
얕은 복사
using System;
namespace CSharp_Test
{
class Test_c
{
public int a;
public int b;
}
public class EmptyClass
{
public static void Main(string[] args)
{
Test_c p1 = new Test_c();
Test_c p2 = p1; // 얕은 복사 발생
p2.a = 20;
Console.WriteLine("p1.a : " + p1.a);
Console.WriteLine("p2.a : "+ p2.a);
}
}
}
<출력>
얕은 복사가 일어난 예시 코드이다.
Test_c형 참조형 변수를 사용하여
p1을 생성하였고 p2에 이를 복사하였다.
이 과정이 얕은 복사이다.
p1과 p2가 같은 주소를 가리키게 되었으므로
p2의 a만 변경했는데도 p1도 변경된 것이다.
깊은 복사
using System;
namespace CSharp_Test
{
class Test_c
{
public int a;
public int b;
// 깊은 복사를 구현한 함수
public Test_c DeepCopy()
{
Test_c instance = new Test_c();
instance.a = a;
instance.b = b;
return instance;
}
}
public class EmptyClass
{
public static void Main(string[] args)
{
Test_c p1 = new Test_c();
Test_c p2 = p1.DeepCopy();
p2.a = 20;
Console.WriteLine("p1.a : " + p1.a);
Console.WriteLine("p2.a : "+ p2.a);
}
}
}
<출력>
깊은 복사를 구현하기 위해서
Test_c 클래스에 DeepCopy라는 함수를 만들어줬다.
DeepCopy 함수 부분을 보면 새로운 인스턴스를 생성한 후,
해당 인스턴스에 있던 a값과 b 값을 그대로 붙여준다.
이 것이 깊은 복사이다.
이런 식으로 새로운 인스턴스를 만들어 반환을 하게 한다.
이렇게 하여 p2의 a 값을 바꿔도 p1의 a 값은 유지된다.