반환형이 참조자이면 어떻게 될까?
코드를 한번보자
#include <iostream>
using namespace std;
int& RefFun(int &ref)
{
ref++;
return ref;
}
int main(void)
{
int num1=1;
int &num2 = RefFun(num1);
num1++;
num2++;
cout<<"num1: "<<num1<<endl;
cout<<"num2: "<<num2<<endl;
return 0;
}
이렇듯 참조의 관계가 하나 더 추가된다.
그런데!! 한가지 기억해야할것이 있는데
이 함수에서 선언된 참조자 ref은 지역변수와 동일한 성격이기에 반환 후 소멸된다.
그러나 참조자는 참조자일뿐!!!! 변수는 아니기에 변수는 소멸되지 않는다.
그럼 다음과 같이 num2를 바꿔보자
#include <iostream>
using namespace std;
int& RefFun(int &ref)
{
ref++;
return ref;
}
int main(void)
{
int num1=1;
int num2 = RefFun(num1);
num1++;
num2++;
cout<<"num1: "<<num1<<endl;
cout<<"num2: "<<num2<<endl;
return 0;
}
num2는 ref값을 복사하는 변수라고 보면될것같다.
이렇듯 반환형이 참조형인 경우, 반환 값을 무엇으로 저장하느냐에 따라서 그 결과에 차이가 있다!!
마지막으로 함수의 반환형을 기본자료형으로 해보자
#include <iostream>
using namespace std;
int RefFun(int &ref)
{
ref++;
return ref;
}
int main(void)
{
int num1=1;
int num2 = RefFun(num1);
num1++;
num2+=100;
cout<<"num1: "<<num1<<endl;
cout<<"num2: "<<num2<<endl;
return 0;
}
어차피 참조자가 참조하는 값이나 변수에 저장된 값을 반환하니 값은 제대로 반환된다.
이렇게해서 출력해보면 두번째 코드와 다를점이 없는데..
다음의 차이가 있다.
이 이유는 두번째 함수의 반환값은 반드시 변수에 저장되어야 하기 때문이다!!!
반환값은 상수나 마찬가지이기 떄문이다.
이러면 안된다!!
다음 코드를 보자
const int num = 20;
int &ref = num;
ref+=10;
cout<<num<<endl;
어떤가!
이게 말이되는가!
상수화한 num 을 ref을 통해서 값을 바꾸면 상수화한이유가 무엇인가!!!
다행스럽게도 씨플플에서는 int &Ref = num;
에서 에어를 일으킨다.
변수 num과 같이 상수화된 변수에 대한 참조자 선언은 다음과 같이 되어야한다.
const int num = 20;
const int &ref = num;
이렇게 하면 ref을 통해서도 값의 변경이 불가능하다.
그런데...
const 참조자는 다음과 같이
const int &ref = 50;
상수도 참조가 가능하다!!!!
아니!!!!
참조자는 변수만 참조가능하다고 했으면서 갑자기 뭔!
상수의 참조냐!!!!
라는 생각은 아래에서 해결하자!
int num=20+30;
과 같이 20,30와 같은 숫자를 가리켜 리터널 또는 리터널 상수라고한다.
이들은 이러한 특징을 지닌다.
"임시적으로 존재한는 값, 다음 행으로 넘어가면 존재하지 않는 상수이다."
뭔 뜻인지 이해가 되는가?!
덧셈연산을 위해서 20,30 모두 메모리 공간에 저장되어야한다.
하지만 저장되었다고 해서 재 참조가 가능한 겂은 아니다.
다음 행으로 넘어가면 소멸되는 상수라고 해도 과언이 아니기 때문이다.
그런데!
이런 상수를 참조하는것이 이치에 맞다고 생각하는가?
const int &ref = 30;
위와같이 말이다!
이는 위에 말대로라면 숫자30이 메모리 공간에 계속 남아 있을때에나 성립이 가능한 문장이다!!!
그래서 c++에서는 위와 같은 것이 가능하게
Const참조자를 이용해서 상수를 참조할 때 '임시변수'라는 것을 만든다.
그리고 이 장소에 상수 30을 저장하고선 참조자가 이를 참조하게끔한다!!!
그런데 궁금증이 들것이다.
"왜 임시변수라는 이상한거까지 끌어들여서 상수의 참조가 가능하게 한거에용..?"
이는 다음 함수 하나를 보자!
int Adder(const int &num1,const int &num2)
{
return num1+num2
}
위와 같이 정의된 함수에 인자의 전달을 목적으로 변수를 선언하는것은 매우 번거로운 일인데 임시변수의 생성을 통한 const참조자의 상수참조를 허용함으로써,
위의 함수는 ㄷ음과 같이 매우 간단히 호출이 가능해진다.
cout<<Adder(3,4)<<endl;
Const 포인터에 대한 복습을 겸할 수 있는 문제를 보자.
다음의 상수 선언을 보자
const int num = 12;
포인터 변수를 선언해서 위 변수를 가리케 해보자.
그리고 이 포인터 변수를 참조하는 참조자를 하나 선언해보자.
마지막으로 이렇게 선언된 포인터 변수와 참조자를 이용해서 num에 저장된 값을 출력하는 예제를 완성하자.
#include <iostream>
using namespace std;
int main(void)
{
const int num =12;
const int*ptr = #
const int *(&ref) = ptr;
cout<<"num : "<<num<<endl;
cout<<"*ptr : "<<*ptr<<endl;
cout<<"&ref : "<<*ref<<endl;
return 0;
}
짠 ~ !