티스토리 뷰

[C#] 참조복사 값복사 (얕은 복사, 깊은 복사)

오후 2:10 2018-04-05 수업내용정리


[TUTO]

[생성자]

객체가 생성될때마다 호출


[스테틱 생성자]

프로그램이 시작되고 (이 클래스가 있는지확인할때) 딱 한번만 실행된다.

그럼 목적이무엇이냐?

스테틱 멤버를 초기화할 목적으로 사용한다.


[]

타입이 사용되기 전에는 딱 한번 컴파일 될 필요가 있다.

이때 타입이있구나 해석이된다. 이때 스테틱 생성자가 호출된다.

타입이 호출될 때. 타입은 한번호출하면 그 다음부터는 호출되지 않는다.

1000개의 타입중 우리가 사용될 타입만 생성되고 인식되는데 이때

스테틱생성자가 스테틱변수(필드)를 초기화할 목적으로 같이 실행된다.


[static]

C#에서는 지역(변수)에 생성할 수 없다.

시스템 내부에서는 static을 전역으로 생성하는데

코드에서는 전역이라는게 없다는 개념으로 이해하면된다.


[]

class Program//이 클래스는 프로그램 자체를 나타낸다.

Program을 고칠일이 없다 실전에선. 매서드추가 및 등등 할일이 거의 없다.





[객체의 복사]

1.객체의복사 shallow(얕은복사)

2.객체의복사 deep(깊은복사)

객체의 복사에서 있는 개념이 깊복,얕복이다.

깉은복사 얕은복사

예시로 struct형의 Point 객체가 int형 x와 y값 그리고 class형 name이라는 멤버를 갖는다면 pt를 생성하게 되면 stack메모리에 구조체가 생기게되며 이때 pt자체가 객체가 된다. 그 후 pt2를 생성해 pt2=pt 이렇게 복사하게 되면 위 사진의 왼쪽과같이 복사가된다. 이때 값이 그대로 복사되는데 문제가되는 점이 바로 마지막 멤버인 클래스형 name멤버는 클래스형이기 때문에 참조자가 가리키는 참조가 복사되어 같은 객체를 가리키게 되는 점이다.

이런 문제로 인해 참조되는 것은 새로 heap에 new로 할당해서 가리키도록 깊은 복사를 해야한다.

값복사 참조복사

클래스형도 마찬가지다. pt가 참조자이고 객체가 heap메모리에 생성되는 것만 다르지 그냥 복사해줄 경우 얕은 복사가 일어난다.

Clone 복사

이때 C#에서 지정해준 Clone을 이용해서 깊은 복사가 가능하게 해준다. 이러한 복사가 가능한 클래스는 ICloneable를 구현하면 된다.

참조복사와 객체복사는 다른거다..

책에서는 참조복사를 할때 얕은 복사라고 하는데 사실 얕복깊복어느것도 아니다.


Struct a와 b에서 b에 a를 복사하면 값까지 복사된다. 이건 얕은 복사라고할 수 있다.


Class pt1,pt2가 있을 때. pt1이 가리키는 객체를 복사해서 pt2가 가리키게하면?

얕은 복사다.....(책엔 깊복이라 되있음)

멤버 대 멤버 복사를 얕은 복라고한다.


값형식의 깊은복사와 참조형식의 깊은복사가 있다.


깊은 복사는 간략히 말하면 객체를 복사할때 그 객체가 가지고 있는 참조자가 가리키는 객체까지

복사해서 참조시켜주는 것 처럼 new해서 가리키게 해주는 것이라고 보면된다.


[get set]


        public int X

        {

            set { x = value; }//예약어 value

            get { return x; }

        }

        public int Y//이때 이걸 프로퍼티(속성)라고 한다.

        {

            set { y = value; }//예약어 value : 지금 당장 들어오는값. 매개변수 같은것

            get { return y; }

        }


위와 같이 하면 C#컴파일러가 함수를 만들어준다.


[ICloneable]

복사가능한 것이면 이 인터페이스를 정의한다.


ICloneable를 가지고 있는 클래스들만 복사가 가능하다고 판단하면된다.


ICloneable을 구현하도록 하면 Clone()함수를 구현해야하며

이때 반환 타입은 object로 정해져있기에 바꿀 수 없다.

때문에 복사를 할 때 타입 형변환을 통해서 복사해준다.

(object->사용자object 다운 캐스트)


[]

C#은 현재 생성자에서 다른 생성자를 호출할 수 있다.

:this()


[소멸자]

~Base()

소멸자는 사실상 쓸일이 없다. 알아서 처리해줌.


[base]

base 부모.

base() 부모 생성자


[상속]

상속하게되면

자식은 생성시 부모기능을 물려받게된다,.


부모쪽은 virtual

상속받는 자식쪽은 override를 해주어서 재정의 해주어야한다.(필요시)


부모클래스를 abstract로 만들어 주면 추상클래스임.

말그대로 객체가 될 수 없다.


동물-사자,말,펭귄

사자는 동물로 자동 업케스팅이 가능.

물려받을게 없더라도, 하나의 타입으로 다루고자 할 경우도

상속을 사용이 가능하다,.


C#은 기본적으로 다중 상속이 되지않는다.

문제가 많아서 없애버림.


[인터페이스]

하나의 타입으로 다룰 수 있게 사용할 수 있따.


인터페이스: 공개되어있는 시그니처.

인터페이스는 상속이 아니라 구현한다라고 표현한다.(impliment)


ex.스타크래프트 유닛....이동. 공격 등


다형성 상속 캡슐화를 적절히 구현할 수 있을 때

확장성 재사용성 수정가능성이 높아지는것.

그런걸 할 수 없다면, 객체지향 프로그래밍 하는 의미가 없어진다.


그렇다고해서 무조건 클래스,다향성,캡슐화 상속 등 한다고해서

좋아지는게 아니라. 변화할 것같은 것을 감안할 수 있도록 코드를 만들어야됨.

적절히... 

다형성을 쓰면 더 복잡해 질 수 있고...

모든걸 높일 순 없다. 트레이드오프. 많은 경험을 통해 얻을 수 있다.

리팩토링 작업.+ 추가 를 병행하는것이 프로그래밍이다.


[과제]

foreach문? 어떻게 될까

ienumable인터페이스를 구현하고 있으면

foreach문을 사용할 수 있다...... 컴파일러가 확인해서

해당 인터페이스를 포함한다면  가능하다고 판단한다.

180405.txt

Program.cs

과제

복습

전화번호부 개선

얕복,깊복 

공유하기 링크
TAG
댓글
댓글쓰기 폼