들어가며
시작하기에 앞서 드디어 본인이 현재 서식하고 있는 지역에서도 코로나 바이러스 확진자가 나왔다.
발이나 손은 반드시 외출 후 세척해야 한다.
신천지 신도라고 환자가 말해주었기에
천만다행으로 빠르게 역학조사가 실시 되었다.
지금 할 수 있는 최선의 방법은 외출을 자제하는 것이지 않을까.
참조형 반환(진) - 중
전 글의 끝 무렵에 코드를 주고 해석을 하고 의미를 찾아오라고 하였다.
우선 그 코드는 다음과 같다.
#include <iostream>
using namespace std;
int& RefRetFuncOne(int& ref)
{
ref++;
return ref;
}
int main()
{
int num1 = 1;
int num2 = RefRetFuncOne(num1);
num1+=1;
num2+=10;
cout << num1 << endl;
cout << num2 << endl;
return 0;
}
그리고 위 코드의 실행 결과는 프로그램의 흐름이 다음과 같음을 증명한다.
num2를 참조자에서 변수로 바꾸고 실행하니
새로운 변수가 선언과 동시에 초기화 된 상황이다.
이렇듯 반환형이 참조형인 경우, 반환된 값을 어떤 것으로 저장하느냐에 따라서
그 결과에 차이가 있음을 확인하였다.
따라서 적절하고 정확한 판단으로 선택해야 한다.
참조형 반환(진) - 하
이제 마지막으로 참조자를 반환하되,
반환형은 기본 자료형인 경우를 이해하기 위해
이전의 코드의 함수 반환형을
int& RefRetFuncTwo(int& ref)
다음과 같이 변경한 후에
int RefRetFuncTwo(int& ref)
실행시킨다면?
우선 두 코드의 차이는 무엇일까.
우선 알 수 있는 것은 함수의 반환형이 다르다는 것이다.
다른 차이점은 보이지 않는가?
정말 보이지 않는가?
유감이다.
안 속는군.
따라서 다음의 코드를 해석해보길 바란다.
#include <iostream>
using namespace std;
int RefRetFuncTwo(int& ref)
{
ref++;
return ref;
}
int main()
{
int num1 = 1;
int& num2 = RefRetFuncTwo(num1);
num1+=1;
num2+=10;
cout << num1 << endl;
cout << num2 << endl;
return 0;
}
'뭐여, 실행 결과가 아까랑 똑같은 뎁쇼?'
정말 그렇게 생각하는가?
뿐만 아니라 실행하였을 때의 과정이나 흐름 또한 [그림 24]와 동일하다.
반환형이 참조형인 'RefRetFuncTwo 함수' 는 반환 값을
다음과 같이 두 가지 형태로 저장할 수 있다.
그에 반에 반환형이 기본 자료형인 'RefRetFuncTwo 함수'는 반환 값을
반드시 변수에만 저장해야 한다.
이유야 조금만 생각해 보면 합리적으로 추론할 수 있다.
반환 되는 값은 당연하게도 '상수(데이터)'나 다를 게 없지 않은가?
따라서 변수에 저장하는 것은 합당하다.
잘못된 참조의 반환
자 그럼 어느정도 개념적인 부분은 이해하였다.
하였다. 아무튼 했다.
그렇다면 이와 관련된 내용은 안 보고도 풀 수 있지 않겠는가?
안 보고 어떻게 문제를 푸는지 궁금한가?
나도 모르니까 알아서 잘 해보길 바란다.
아무튼 다음 코드를 보고 논리적으로 무엇이 잘못 되었는지 확인해보라.
int& RetRefFunc(int n)
{
int num = 20;
num += n;
return num;
}
'음, 잘 모르겠는뎁쇼.'
얼핏보면 뭐가 잘못 된 것인지 잘 모를 수도 있을 것이다.
힌트를 주자면 '반환형과 반환값'이다.
'그래도 모르겠는뎁쇼.'
모르겠다고만 하지 말고 생각을 해보라.
목 위에 달려 있는 것이 원효 대사 전용 텀블러가 아니라면 말이다.
'와 선넘네, 말넘심;;'
사실 본인도 답을 보기 전에는 똑같은 반응이었다.
나한테도 하는 말이기도 하니 너무 그러지 말길 바란다.
아무튼 조금 더 생각해 보고 아래에서 답을 확인하도록 하자.
위에서 힌트로 반환형과 반환값을 제시하였다.
반환형은 'int&'이고 반환값은 'num'이다.
따라서 위의 함수에서의 지역 변수 'num'은 저장된 값을 반환하지 않고,
'num'을 참조의 형태로 반환하고 있는 것이다.
그러므로 다음의 코드로 함수를 호출하게 되면
int& ref = RetRefFunc(10);
지역 변수 'num'에 'ref'라는 참조자가 하나 더 생성되는 상황이 발생한다.
'필자양반, 그냥 참조자가 하나 더 생기는 거잖수. 이왜안?'(이게 왜 안됨?)
극락에서 원효 대사가 텀블러 컬렉션 하나 늘었다고
탭댄스를 추며 반야심경을 외는 소리가 여기까지 들리는 것 같다.
우린 조금 더 깊이 생각해 볼 필요가 있다.
함수가 반환 되면 참조의 형태로 반환된 'num'은 변수 효력 지역을 이탈하여
애니메이션의 비련의 여주인공마냥 먼지가 되어 소멸된다.
그렇게 되면 참조자 'ref'는 소멸된 'num'를 어떻게 참조할 수 있겠는가?
그리고 이후의 코드는 어떻게 되겠는가?
사실 나도 모른다.
하지만 정확한 것은 프로그래머가 원하는 결과가 출력될 가능성은 절대적으로 낮다.
요약하자면, 지역 변수를 참조형으로 반환하는 실수를 유의해야 한다는 것이다.
마치며
요즘 영 공부할 맛이 안 난다.
계속 집에만 있어서 그런 것이 확실하다.
공간은 분할이 가장 중요하다고 생각하는 만큼이나
뭔가 하고자 했을 때 능률이 떨어지는 것 같다.
빨리 이 시국이 종식되었으면 하는 바람이다.
참고 및 출처
윤성우의 열혈 C++ 프로그래밍