[Csharp]깊은 복사
📚복사와 참조
C#의 클래스는 기본적으로 참조로 동작하고 구조체는 복사로 동작한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
// 참조
class Knight
{
public int hp;
public int attack;
public void Move()
{
Console.WriteLine("Knight Move");
}
public void Attack()
{
Console.WriteLine("Knight Attack");
}
}
// 복사
struct SMage
{
public int hp;
public int attack;
}
static void KillMage(SMage mage)
{
mage.hp = 0;
}
static void KillKnight(Knight knight)
{
knight.hp = 0;
}
static void Main(string[] args)
{
SMage mage;
mage.hp = 100; // KillMage 함수를 호출해도 값이 변하지 않음
mage.attack = 3;
KillMage(mage); // mage가 복사로 전달됨
Knight knight = new Knight();
knight.hp = 100; // KillKnight 함수를 호출하면 값이 0으로 변함
knight.attack = 5;
knight.Move();
knight.Attack();
KillKnight(knight); // knight가 참조로 전달됨
}
📚얕은 복사
기존에 만들었던 기사 개체(object)를 다른 기사 클래스에 대입해보면 아래와 같다.
1
2
3
4
5
6
7
8
static void Main(string[] args)
{
Knight knight = new Knight();
knight.hp = 100;
Knight knight2 = knight; // 얕은 복사
knight2.hp = 0;
}
knight2에 knight를 복사하고 knight2의 hp를 0으로 수정하면 클래스는 참조로 동작하기 때문에 knight의 hp도 0이 되는 것을 확인 할 수 있다.
첫 번째 기사 개체를 만든 다음 이후에 만들 기사 개체들은 독립적으로 관리하면서 처음 만들었던 기사의 속성(hp, attack)만 초기값으로 가지고 있게 하려면 깊은 복사가 필요하다.
📚깊은 복사
얕은 복사가 되지 않게 새로운 개체를 하나 더 만들어서 그 곳에 복사를 해도 되지만 기사 클래스 안에서 깊은 복사가 되게끔 함수를 추가해서 해결할 수 있다. (기사 개체는 기사 클래스가 관리하도록 하는 것이 좋을 것 같다.)
Knight를 반환하는 Clone() 이라는 함수를 정의하면 아래와 같다. Clone() 함수를 호출하면 기사 개체를 새로 만들고 그 개체의 hp와 attack 값에 원래 기사가 가지고 있던 값을 대입한다. 마지막으로 새로 만든 기사의 개체를 반환한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class Knight
{
public int hp;
public int attack;
// 깊은 복사
public Knight Clone()
{
Knight knight = new Knight();
knight.hp = hp;
knight.attack = attack;
return knight;
}
public void Move()
{
Console.WriteLine("Knight Move");
}
public void Attack()
{
Console.WriteLine("Knight Attack");
}
}
얕은 복사와 달리 깊은 복사를 하면 기존 knight의 hp가 0으로 바뀌지 않고 새로 만든 기사 개체의 hp만 0으로 바뀌는걸 확인할 수 있다.
1
2
3
4
5
6
7
8
static void Main(string[] args)
{
Knight knight = new Knight();
knight.hp = 100;
Knight cloneKnight = knight.Clone(); // 깊은 복사
cloneKnight.hp = 0;
}
Leave a comment