삽질의 현장/- .NET

#022_닷넷(.NET)_.Net Framework 기본 - 참조 타입과 값 타입에 대하여

shovelman 2015. 10. 24. 16:23


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


이번시간에는 구조체, 클래스, 참조 타입, 값타입에 대한

사용, 활용, 비교에 대해서 알아보고자 합니다.


이전 시간에 우리가 이 참조 타입과 값 타입을 비교하며 

'복사'를 했을 때에 대한 메모리를 그려본 기억이 있습니다.




그런데... 매개 변수로 각 타입을 넘길 때도 다를 것이 없습니다.



물론, 차이가 있다면

매개변수는 그 해당 함수가 끝나면 사라진다는 것이지요...


여담으로 만약, 함수로 전달 되는 매개변수의 크기가 크고 무겁다면(?)

참조 타입을 사용하는 것이 프로그램을 위해 좋겠지요...


객체를 반환하는 메서드를 일반적으로 우리는 '펙토리 메서드'라고 부릅니다.

Struct나 Class나 모두 객체를 반환할 수 있습니다.

그렇다면 만약, 펙토리 메서드와 같이 

메서드를 통해 객체를 생성후 반환한다면 그 메모리 구조는 어떨까요?


우선 아래의 예제 코드를 살펴보신 다음 메모리 구조를 이해해보시길 바랍니다.



메서드가 먼저 수행이 되고 return 된 값이 객체에 대입이 됩니다.

즉, 위의 예제 코드에서는 MakePointS(), MakePointS() 메서드가 호출이 되고

해당 메서드들의 stack에 객체의 이름은 아직 모르지만, 지역 객체가 만들어지는 것입니다.

그리고 return을 하게 되면 그 return 된 복사본을 객체에 담는 것이지요...


다음은 메모리 구조입니다.



즉, 함수에 지역 객체가 생성되었다가 함수가 종료되자마자 사라지고

함수 return 시 복사본이 Main() Stack에 하나 만들어지는데

이 값을 main의 객체에 대입시켜주는 것입니다.


그런데 클래스의 경우는 조금 다릅니다.

Heap 영역은 참조를 버리기 전까지 절대로 사라지지 않습니다.

따라서 메서드에서 객체를 생성하고 반환되면 

Main() 에 있던 참조자가 그 객체를 참조하게 되는 것입니다.



뭐 함수를 만들어 객체를 생성하던, 

그냥 객체를 생성하던 다를바가 뭐냐...라고 말씀하시면...

객체를 생성하는 부분에 있어서 Logic으로써 하나의 구성을 이룰 수 있습니다.

즉, 펙토리 클래스를 만들고 

해당 클래스로부터 만들어진 객체는 생성만 담당하도록 만드는 것이지요...


우리는 지금까지 알아본 정보에 의해서 결론을 내리자면

참조 타입이던 값 타입이던 인수 타입, 반한 타입이 모두 가능하다는 사실을 알게되었습니다.


 

위의 예제 코드들에 대해서 생각해보시길 바랍니다...

좌측의 코드는 

복사받은 객체 및 참조자가 가리키는 주소로 부터 필드 값을 변경시키는 코드입니다.


구조체 객체를 매개변수로 전달 했어도,

이는 값 복사에 지나지 않기 때문에 실제 Main()에 있는 구조체 객체(pt1)는 변화가 없습니다.

하지만, 클래스 객체인 pt2는 값이 변경이 됩니다.


그런데 만약 우측의 코드와 같은 경우는 어떨까요?

이때에는 둘다 변화가 일어나지 않습니다.

그 이유는 SetPointS(), SetPointC()의 pt는 지역적이기 때문입니다.


우선, Main()에서 객체를 생성했습니다.



다음으로 함수를 호출하는데, 매개변수로 객체들을 전달하군요...

이때 이 함수들의 메모리 구조를 보면 아래와 같습니다.



하지만, SetPoint() 함수가 return 되는 순간 다 날라가지요...


그런데 만약 이 문제에 대해서 해결하고 싶다면

이처럼 코드를 구현할 수 있습니다.



이처럼 out 파라메터를 통해 매개변수로 전달 시키면 

Main에 있는 pt1, pt2 객체 및 참조자의 것과 다름 없어집니다.



그리고 Class를 매개변수로 보낼 경우

out 파라메터를 통해 클래스를 보내기 때문에 새로운 객체의 참조를 받게되지요...

따라서 기존의 객체는 가비지 컬렉션 대상인 객체가 되어버립니다.

머지않아 사라지겠지요...


자... 참조와 값이라는 개념부터 시작됬습니다. 

기초적인 내용부터 이해가 가시지 않는다면 아마 이해하시기 힘드셨을 것입니다...


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


이상 삽잡이였습니다!