-
얕은 복사와 깊은 복사 (Shallow copy and deep copy)유니티 개발/C# 2021. 10. 11. 16:07
이전에 게임을 만들던중 Monster라는 동일 클래스를 복사해서 서로 능력치가 다른 몬스터를 만들어 보려 한적이 있습니다.
몬스터라는 클래스를 Monster cat = new Monster() 로 초기화 시키고 그 클래스에 있는 speed 라는 변수를 조절한다음, Monster dog = cat; 으로 복사하여 다시 speed를 조절해 각자 속도가 다른 고양이와 강아지를 만들어 보려고 했었죠.
허나 게임을 실행하자 고양이와 강아지는 서로 같은 속도로 움직였습니다. 왜 이런일이 발생했을까요?
1. 얕은복사
1234567891011121314151617public class Monster{public int speed;}public class Test : MonoBehaviour{private void Start(){Monster cat = new Monster();cat.speed = 3;Monster dog = cat;dog.speed = 2;print($"고양이 속도 : {cat.speed}, 강아지 속도 : {dog.speed}");}}cs 몬스터 클래스로 강아지와 고양이를 생성하는 코드
그림1. 실제로 입력된 고양이와 강아지 속도 위 코드를 실행하면 실제로 입력한 속도값이 아닌 마지막으로 입력한 속도값으로 출력이 됩니다. 그 이유는 클래스는 값 형식이 아닌 참조 형식이기 때문에 다른 인스턴스를 사용해도 원본 클래스의 값을 수정하도록 설계되어 있기 때문입니다. 즉 인스턴스는 두개이지만, 실질적으론 같은 값을 참조하고 있는거지요.
스택과 힙의 개념으로 살펴보면 스택에는 cat만 생성되고, 같은 힙에서 값을 바꾸려 하고 있습니다. 우리는 cat을 복사받아 dog의 정보를 별도로 힙에 보관해야 합니다. 어떻게 해야할까요?
2. 깊은복사
12345678910111213141516171819202122232425public class Monster{public int speed;public Monster DeepCopy(){Monster newMonster = new Monster();newMonster.speed = this.speed;return newMonster;}}public class Test : MonoBehaviour{private void Start(){Monster cat = new Monster();cat.speed = 3;Monster dog = cat.DeepCopy();dog.speed = 2;print($"고양이 속도 : {cat.speed}, 강아지 속도 : {dog.speed}");}}cs DeepCopy() 메서드가 추가된 코드
그림2. 변경된 고양이와 강아지의 속도 위의 코드처럼 별도로 DeepCopy 메서드를 만들어주면 인스턴스가 새로운 값을 참조하여 힙에 할당하게 됩니다.
깊은 복사가 필요한 클래스가 있으면 위 코드를 참조하시면 좋을듯합니다.
'유니티 개발 > C#' 카테고리의 다른 글
가변 인수가 있는 메서드 (Method with variable arguments) (0) 2021.10.04