C#클래스 (2)

#1. 얕은 복사


class myclass
    {
        public int field1;
        public int field2;
    }
    class Program
    {
        static void Main(string[] args)
        {
            myclass source = new myclass();
            source.field1 = 10;
            source.field2 = 20;

            myclass target = source;
            target.field2 = 30;

            Console.WriteLine("{0} {1}", source.field1, source.field2);
            Console.WriteLine("{0} {1}", target.field1, target.field2);

        }

    }

target.field2를 30으로 넣어주었을 뿐인데 source.field2 까지 30으로 바뀌어 버렸다.

이런 현상이 일어나는 이유는 바로 클래스 역시 참조 형식의 데이터 형식(자료형)이기 대문이다.

앞서서 참조 형식에 대해서 언급했지만 여기서도 복습하는 차원에서 간략하게 다시 정리하겠다.

참조 형식: 힙영역에 객체를 할당하고 스택에 있는 참조가 힙 영역에 할당된 메모리를 가리킨다.

즉 스택에 있는 source.field2와 target.field2는 같은 메모리를 가리키고 잇기 때문에 둘중에 어떤것을 바꾸던간에 둘다 값이 바뀌게 되는 것이다.

이같이 객체를 복사할때 참조만 복사하는것을 얕은 복사라고 한다.

#2. 깊은 복사.

얕은 복사의 문제점을 해결하기 위해서는 target이 힙에 보관되어 있는 내용을 source로부터 복사 받아 별도의 힙 공간에 객체를 보관해주는 방법을 사용해야 한다.

이 같은 방법을 깊은 복사(Deep Copy)라고 한다. C#에서는 깊은 복사의 기능을 직접 제공하지 않기 때문에 프로그래머가 직접 깊은 복사를 하게끔 해줘야 한다.

using System;

namespace test
{
    class myclass
    {
        public int field1;
        public int field2;

        public myclass DeepCopy()
        {
            myclass newCopynew myclass();
            newCopy.field1=this.field1;
            newCopy.field2=this.field2;

            return newCopy;
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            myclass source = new myclass();
            source.field1 = 10;
            source.field2 = 20;
            myclass targetnew myclass(); 

            //myclass target = source;
            //target=source;
            target = source.DeepCopy();
            target.field2 = 40;
            source.field1 = 30;            
      Console.WriteLine("{0} {1}"source.field1source.field2);
      Console.WriteLine("{0} {1}"target.field1target.field2);
    
        }
        
    }
}

클래스 안에 DeepCopy() 라는 메소드를 만들었다. 메소드 구조를 보자면..
  ㅡ 새로운  객체를 안에서 생성해준다.(새로만들어진 객체는 힙으로)

  ㅡ현재객체(this)에 있는 멤버들을 새로운객체(newCopy)에 있는 멤버들에 대입한다.

  ㅡ복사된 객체를 리턴한다.

이렇게 하면 같은 곳을 참조하지 않기 때문에 데이터의 손실이 일어나지 않는다.

#3. this 키워드

위에 깊은복사를 하다가 DeepCopy() 안에서 이상한 키워드를 보지 못하는가? this라는 키워드를 보았을 것이다.

this 키워드는 객체가 자신을 지칭할때 사용한다.

여기서의 this 는 MyClass 자신을 말한다. 즉 this.field1 == myclass.filed1 이라는 공식이 성립된다.

#4. this() 생성자


위에 this 키워드가 객체 자신을 지칭하는 것을 말한다면,  this()생성자는 자기 자신의 생성자를 가리킨다.

this()생성자는 생성자에서만 사용할 수 있다.

class myclass
    {
        public int field1;
        public int field2;
        public int abc;
        public myclass DeepCopy()
        {
            myclass newCopynew myclass();
            newCopy.field1=this.field1;
            newCopy.field2=this.field2;
           Console.WriteLine("test{0} test1{1}",this.field1,this.field2);
            return newCopy;
        }
        public myclass()
        {
            this.a = 100;
        }

        public myclass(int b) : this()
        {
            this.b = b;
        }

        public myclass(int bint c) : this(b);
        {
            this.cc;
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            myclass source = new myclass(3,4);

  Console.WriteLine("{0} {1} {2}"source.asource.bsource.c);
            
        }
        
    }

Post a Comment

다음 이전