삽질의 현장/- .NET

#020_닷넷(.NET)_.Net Framework 기본 - 실제 참조 타입 과 값 타입

shovelman 2015. 10. 24. 09:52


안녕하세요 삽잡이입니다.


이번 시간에는 실제로 값 타입과, 참조 타입이 뭔지 알아가도록 해보겠습니다...

지난 시간에 복습하느라 못했습니다...


사실 실제 값 타입, 참조 타입은 

'Class'와 'Struct' 이 두가지만 알면 됩니다...

클래스와 구조체를 통해 값 타입과 참조 타입을 명확하게 구분할 수 있기 때문입니다.

왜냐? 클래스는 참조의 대표, 구조체는 값의 대표이니깐 말입니다.


우선 둘의 특징에 대해서 알아보고 가도록 하겠습니다.



우선 Class는 부모가 Value 타입이 아닌 이상

모든 부모로부터 모든 타입을 상속받을 수 있습니다.

또한 파생시킬 수 있습니다. 즉, 자식 클래스를 만들 수 있다 이겁니다.


하지만, Struct는 상속이 자체가 불가능합니다.

또한 상속을 받을 수도, 상속을 시켜줄 수도 없습니다.

값을 표현하기 위해 만든 형식이기 때문입니다... 

즉, 어떤 값, 정의를 나타내려고 만든 형식이란 말입니다. 꽉 막힌 녀석이군요...


이 둘의 가장 큰 차이점은 

Class 는 객체가 Heap 영역에 만들어지고, Struct는 Stack 영역에 만들어진다는 것입니다.


아까 만들어 놓은 구조체와 클래스를 통해 객체를 생성해보겠습니다.



문법상으로는 똑같습니다.

하지만 Struct의 new는 Heap 영역에 할당하겠다는 new 키워드가 아닌 

초기화의 new 키워드입니다

즉, 초기화를 하겠다는 new 키워드라는 뜻입니다.


왜 굳이 이렇게 new 키워드를 써야할까요...

구조체에서는 new 키워드를 사용 못하게 하지 않은 이유에 대해 궁금하시지 않습니까...

뭐... Class로 만들어 놓은 코드를 Struct로 바꾸고 싶다면

코드를 고치지 않고 바꿀 수 있도록... 즉, '호환'이 되도록 만들어 놓은것 아닐까요...?

아니면... 뭐... 말고요...


사실, 구조체는 new 없이도 사용이 가능합니다.

구조체에 new 키워드를 사용하면 '명시적인 초기화'가 가능한 것이지요...

구조체는 new 키워드를 사용해도 Heap 영역에 만들어지는 것이 아닙니다.

단지 생성자를 호출하기 위한 키워드일 뿐입니다.


아무튼... 위의 객체들을 생성하면 메모리상 이렇게 그려질 수 있습니다.


 

Class는 Heap 영역에 생성된 객체를 Stack 영역에 있는 참조자가 참조를 하지만,

이와 다르게 Struct는 Stack 영역에 객체가 생성되는 것을 알 수 있습니다.

따라서, ptc는 참조자이지만, pts는 자체가 객체의 이름이 됩니다.

사용 방법은 똑같지만 단지 stack에 만들어지는 객체라는 차이가 있는 것입니다.


이 둘은 분명히 차이가 있습니다.

만약 각각 객체들을 복사하게 되면 어떻게 될까요?

잘 생각해보셔야합니다...



Class는 참조가 복사되기 때문에 같은 객체를 가리키는 참조가가 하나 생기는 것이지만, 

Struct는 객체가 복사가 되는 것입니다.

즉, 전자는 참조가 복사되는 것이지만, 후자는 값이 복사된다는 것입니다.


이것이 바로 참조 객체와 값 객체의 핵심적인 차이입니다.

정리해볼까요?

Struct는 Stack 영역에 객체가 만들어지고 

객체를 복사하면 값이 복사가 되는 것이고,

Class는 Heap 영역에 객체가 만들어지고 

참조자만 복사될 뿐 같은 객체를 가리킨다 이겁니다.


구조체에는 기본 생성자가 예약되어있습니다.

컴파일러와 약속을 했지요...

따라서 뭐... 구조체에 생성자를 쓰는 경우가 있긴할지 모르겠으나,

기본 생성자를 구현해봤자 오류가 나는 사실을 기억하시길 바랍니다.

뭐... 기본 생성자가 아니라면 구조체도 생성자를 구현할 수 있습니다.


다시 말씀드리지만, 

구조체는 기본 생성자를 가질 수 없습니다. 에약되어있기 때문입니다.

컴파일러가 만들어 놓기 때문에 우리는 만들 수 없습니다.


마지막으로 하나만 더 살펴보도록 하겠습니다.


PointS pts1 = PointS(1,1);


PointS 형식을 구조체라고 생각해보시길 바랍니다.

이런 문법이 존재할까요?

이럴 때에는 생성자를 호출하여 초기화를 한다는 의미입니다.

따라서 new 키워드가 필요하지요... new 가 없으면 안됩니다.


이번 시간은 여기까지 하도록 하겠습니다.


이상 삽잡이였습니다!