전체 코드

using System.ComponentModel;
using System.Numerics;
using System.Threading;

namespace CSharp
{
    // 참조

    class Knight
    {
        public int hp;
        public int attack;

        public void Move()
        {
            Console.WriteLine("Knight Move");
        }
        public void Attack()
        {
            Console.WriteLine("Knight Attack");
        }
        public Knight Clone()
        {
            Knight knight = new Knight();
            knight.hp = this.hp;          // 현재 객체의 hp를 복사
            knight.attack = this.attack;  // 현재 객체의 attack을 복사
            return knight;                // 복사된 객체 반환
        }
    }

    // 복사
    struct Mage
    {
        public int hp;
        public int attack;
    }

    internal class Program
    {
        // 복사와 참조
        static void KillMage(Mage mage) 
        {
            mage.hp = 0;
        }

        static void KillKnight(Knight knight)
        {
            knight.hp = 0; 
        }

        static void Main(string[] args)
        {

            Mage mage;

            mage.hp = 100;
            mage.attack = 10;
            KillMage(mage);


            Mage mage2 = mage;
            mage2.hp = 0;
            Knight knight = new Knight();
           
            KillKnight(knight);
            knight.hp = 100;
            knight.attack = 10;
            knight.Move();
            knight.Attack();


            //Knight knight2 = knight;
            //knight.hp = 0;

            //Knight knight2 = new Knight();
            //knight2.hp = knight.hp;
            //knight2.attack = knight.attack;

            // DeepCopy(깊은 복사)
            Knight knight2 = knight.Clone();
            knight2.hp = 0;
        }

    }
}

1️⃣ 구조체(Struct) vs 클래스(Class) 차이

구분구조체(Struct)클래스(Class)
타입값 타입(Value Type)참조 타입(Reference Type)
메모리 저장 위치스택(Stack)힙(Heap)
복사 방식Call by Value (값 복사)Call by Reference (주소 복사)
할당 방식Mage mage; 선언만으로 메모리 할당됨Knight knight; 선언만으로는 메모리 할당 X (new 필수)
객체 복사새로운 객체가 생성됨 (독립적인 사본)기본적으로 참조가 복사됨 (같은 객체를 공유)
사용 사례간단한 데이터 저장객체의 동작과 상태를 관리

구조체(Struct) → 값 타입이므로 독립적인 복사본을 생성
클래스(Class) → 참조 타입이므로 동일한 객체를 공유 (얕은 복사)


3️⃣ 코드 분석 (상세 설명)

📌 1) 구조체(Struct) - 값 타입 복사

    struct Mage
    {
        public int hp;
        public int attack;
    }

구조체는 값 타입(Value Type)으로, 복사 시 새로운 독립적인 객체가 생성됨
스택(Stack) 메모리에 저장Mage mage2 = mage; 하면 새로운 메모리가 할당됨
Mage 구조체를 복사하면 hpattack 값이 그대로 복사되지만, 두 객체는 서로 영향을 주지 않음

Mage mage;
mage.hp = 100;
mage.attack = 50;

Mage mage2 = mage;  // 값 복사
mage2.hp = 0;       // mage2의 hp만 변경, 원본 mage는 영향 없음

📌 2) 클래스(Class) - 참조 타입 복사

    class Knight
    {
        public int hp;
        public int attack;
    }

클래스는 참조 타입(Reference Type)으로, 복사 시 같은 객체를 가리킴
힙(Heap) 메모리에 저장Knight knight = new Knight(); 해야 객체가 생성됨
Knight knight2 = knight; 하면 knight2와 knight는 같은 객체를 공유

Knight knight = new Knight();
knight.hp = 100;
knight.attack = 10;

Knight knight2 = knight;  // 얕은 복사
knight2.hp = 0;           // knight2의 hp를 변경하면 knight도 변경됨

➡ knight2는 knight와 동일한 객체를 참조하기 때문에 하나를 변경하면 나머지도 변경됨 (얕은 복사).


📌 3) 깊은 복사(Deep Copy)

    public Knight Clone()
    {
        Knight knight = new Knight();
        knight.hp = this.hp;
        knight.attack = this.attack;
        return knight;
    }

Clone() 메서드를 사용하여 새로운 객체를 생성하고 모든 속성을 복사
Knight knight2 = knight.Clone(); 하면 knight2는 knight와 독립적인 객체

Knight knight = new Knight();
knight.hp = 100;
knight.attack = 10;

Knight knight2 = knight.Clone();  // 깊은 복사
knight2.hp = 0;                   // knight2의 hp만 변경됨, knight는 영향 없음

📌 4) 매개변수 전달 - 값 타입 vs 참조 타입

    static void KillMage(Mage mage)
    {
        mage.hp = 0;  // mage 구조체를 복사하여 사용 (원본 영향 없음)
    }

    static void KillKnight(Knight knight)
    {
        knight.hp = 0;  // knight 객체의 참조를 전달받아 원본이 변경됨
    }

구조체(값 타입)KillMage(mage);를 호출해도 원본 mage는 변경되지 않음
클래스(참조 타입)KillKnight(knight);를 호출하면 원본 knighthp가 0으로 변경됨

Mage mage;
mage.hp = 100;

KillMage(mage);  // 호출 후에도 mage.hp == 100 (영향 없음)

Knight knight = new Knight();
knight.hp = 100;

KillKnight(knight);  // 호출 후 knight.hp == 0 (원본 변경됨)

profile
李家네_공부방

0개의 댓글