반응형
우선 몇가지 용어? 정리를 좀 해보자..

OOP에 대한 자료를 보다보면, 객체, 인스턴스란 말이 참 많이도 나온다.. (설마, 변수, 상수가 뭐예요? 그럼 혼난다..) 객체와 인스턴스가 뭘까?

간단하게 생각하자.. 객체는 틀이고, 인스턴스는 결과물이야.. 붕어빵 먹고 싶은데, 재료들과 빵틀만 있으면 아무 소용이 없지..? 빵틀에 재료 넣고 만들어야 먹을 수 있잖아.. 빵틀에서 만들어져 나온 그 붕어빵이 인스턴스라고 생각하면돼.. 헤깔린다고? 더 간단히 하면, 객체는 개념적으로만 존재하는 거구, 인스턴스는 진짜 있는거야.. 그래도 모르겠다면, 그냥 넘어가자.. 엄청 중요한건 아니거든.. 다만 가끔 헤깔릴 뿐이지..

전에 값타입이네, 참조타입이네 그런 이야기를 했었어.. 이걸 약간 더 깊게 볼까 하고 있어.. C/C++에서 포인터 해본사람은 이해가 쉬울꺼야.. 뭐 이것도 아주 중요한 건 아니니 그냥 편하게 읽고 지나가도 무방할꺼야..왜냐면, 예전 16비트 시스템같이 어플이 가질 수 있는 메모리가 제한적이거나 할경우 스택 오버플로우나 뭐 그런 일이 발생해하면 골치 아파졌지만, 요새 윈도우는 그거 넘기기가 더 힘들어서.. 그냥 막 써두 돼.. 요샌 메모리도 하드디스크도 넉넉하잖아..
 
아무튼 기본적으로 값타입이란 녀석은 스택에 참조타입이란 녀석은 힙에 자기 자리를 잡어.. 정확히는 참조타입은 스택에 이정표를 하나 더 남겨 놓지만...

우선 값타입은 선언과 동시에 스택에 차곡 차곡 자리를 잡아..(스택이 뭔진 알지?), 반면, 참조타입은 나중에도 나오겠지만, 선언 -> 인스턴스 생성의 과정을 거치기 때문에 선언시엔 스택에 이정표를 콕 꼽아 놓고 인스턴스가 선언되면 그 이정표에 "어디어디에 있슈.."란 표시를 만들어..

왜 스택과 힙을 사용하는지 궁금한 사람은 OS개론같은 그런 책을 참조하도록..

그럼 다시 값타입의 특징부터 다시 보자.. 값타입의 특징을 요약하면, 선언과 동시에 메모리가 할당되고, (스택에)
int a = 5;
int b = a;
와 같이 치환 연산시 b에 a의 값인 5가 복사되는 형식이야.. 다시말해, a와 b는 각각 다른 메모리란 이야기지..

반면 참조타입은 선언(스택)을 하고 반드시 인스턴스를 생성(힙)해 주어야 하고, 
class refType
{
    public int a = 0;
};

...

refType rt1 = new refType();
rt1.a = 1000;
refType rt2 = rt1;

이렇다면, rt1과 rt2의 스택에서의 주소공간(선언만 한 상태)은 틀리지만, 실제적인 값이 존재하는 힙의 주소는 동일하게 되어 rt2.a도 1000이란 값을 갖게돼.. 즉, 참조타입은 주소값만 복사가 되지 실제 값은 복사가 안된다는 소리기도 하고..

이걸 이야기 하는 이유는 나중에 어플 작성하다 보면 가끔 헤깔리는 경우가 있거든.. 쓰다보면 익숙해 질꺼야.. 걱정말어..

자, 그럼 이제 매개변수 전달에 대해 좀 알아보자.. 우리가 일반적으로 보는 함수는 아래와 같이

int function(int a, int b)
{
    a = 8;
    b = 11;

    return a+b;
}

이런 식이잖아..  매개변수(argument)를 자세히 봐.. 
저게 값타입이니 참조 타입이니? 이제부터 그걸 이야기 하려고 하는거야..
위에 예는 값타입이지?

내가 만약 저 함수를 호출하는 측에서 아래와 같이

...
int a = 5;
int b = 3;
                                        <- 1
int c = function(a, b);
                                        <- 2
...                                     

이라고 했다면, 
1번과 2번 지점에서의 a, b값은 얼마일까?

다 맞췄길 바란다.. 변화 없이 a = 5, b = 3이다.. 이 말인 즉, 위와 같은 경우 매개변수는 값타입에 의한 전달이 이루어 진다는 소리다. 함수 밖의 a, b와 함수안의 a, b는 전혀 다른 메모리에 존재한다는 이야기이다. 그런데 까끔은 함수 내부에서의 변화를 함수 바깥까지 연결 시켜야 할 경우가 발생하기도 한다..
 그런경우에 사용하는게 바로 'ref'란 키워드이다.

아래를 보자.

int function(ref int a, int b)
{
    a = 8;
    b = 11;

    return a+b;
}


...
int a = 5;
int b = 3;
                                        <- 1
int c = function(a, b);
                                        <- 2
...                     

와 같다면 1, 2는?

그렇다. 1에선 a = 5, b = 3이고, 2에선 a = 8, b = 3이다.. a를 참조형식으로 받으라고 친절하게 ref란 키워드를 붙여줬기 때문에 a는 함수 내부의 변화에 영향을 받았지만, b는 그냥 값 형식으로 넘어갔기 때문이다. 그런데 여기서 주의해야 할 점이 있다.. ref키워드를 사용하는 변수는 반드시!! 초기화가 되어 있어야 한다.

즉, 
...
int a;
int b;

int c = fuction(a, b);
...
하면 안된다는 이야기다. 

만약, 변수 a가 함수 호출 이후에나 유효한 값 즉, 호출 이전에 초기화 할 필요가 없는 값이라면? 
이런 경우 불필요한 연산을 줄이기 위해 "out"이란 키워드를 제공한다. 이 키워드는 참조형식으로 매개 변수를 전달하지만, 초기화를 하지 않은 매개변수가 사용가능하도록 해 준다.
즉, 
int function(out int a, int b)
{
    a = 8;
    b = 11;

    return a+b;
}
...
int a;
int b;

int c = fuction(a, b);
...
위와 같이 사용 가능하다는 이야기다.



반응형

+ Recent posts