참조자의 활용에는 함수가 큰 위치를 차지함.
1.Call-by-value & Call-by-reference
//Call-by-value
void SwapByValue(int num1, int num2)
{
int temp = num1;
num1 = num2;
num2 = temp;
}
int main(void)
{
int val1 = 10;
int val2 = 20;
SwapByValue(val1, val2); //val1과 val2에 저장된 값이 바뀌기를 기대함
cout << "val1: " << val1 << endl; //10 출력
cout << "val2: " << val2 << endl; //20 출력
return 0;
}
예상된 결과가 나오지 않는 이유: 어찌보면 당연...
함수 내에서만 효력이 존재하기 때문에 나오면 그 값이 반영되지 않고 기존의 10, 20을 출력함.
//Call-by-reference
void SwapByRef(int * ptr1, int * ptr2)
{
int temp = *ptr1;
*ptr1 = *ptr2;
*ptr2 = temp;
}
int main(void)
{
int val1 = 10;
int val2 = 20;
SwapByValue(&val1, &val2); //val1과 val2에 저장된 값이 바뀌기를 기대함
cout << "val1: " << val1 << endl; //20 출력
cout << "val2: " << val2 << endl; //10 출력
return 0;
}
포인터를 들고 가기 때문에 예상된 값이 나옴.
2.Call-by-address? Call-by-reference!
call-by-address라고 부르지 않는이유: 주소 값이 전달되었다는 사실이 중요한 게 아니라, 주소값이 참조의 도구로 사용되었다는 사실이 중요!
int * SimpleFunc(int * ptr)
{
return ptr + 1; //주소값을 증가시켜서 반환
}
//call-by-reference아님
int * SimpleFunc(int *ptr)
{
if(ptr == NULL)
return NULL;
*ptr = 20;
return ptr;
}
//함수 외부에 선언된 변수를 '참조'함
//Call-by-reference
C++에서는 함수 외부에 선언된 변수의 접근 방법으로 두 가지가 존재함.
1.주소 값을 이용한 Call-by-reference
2.참조자를 이용한 Call-by-reference
3.참조자를 이용한 Call-by-reference
참조자가 좋은 이유... 랄까
매개변수는 함수가 호출되어야 초기화가 진행되는 변수들이므로 매개변수에 있다고 초기화가 이루어지지 않은 것이 아니라, 함수 호출 시 전달되는 인자로 초기화를 하겠다는 의미임.
윤성우 C++ p.80 3번 정답
ptr1, ptr2를 매개변수로 넣으라고 했으므로..
#include <iostream>
using namespace std;
void SwapPointer(int *(&pref1), int *(&pref2))
{
int *ptr = pref1;
pref1 = pref2;
pref2 = ptr;
}
int main(void)
{
...
SwapPointer(ptr1, ptr2);
...
}
참조자의 이점: 포인터보다 잘못 사용할 확률 적고 활용이 쉬움
4.참조자를 이용한 Call-by-reference의 황당함과 const참조자
참조자의 단점
call-by-value가 아닌게 단점이 됨
원래같으면
int num = 24;
HappyFunc(num);
cout << num << endl;
-> call-by-value로 인해 24가 출력되어야 하지만
void HappyFunc(int &ref) { . . . } 이 되면 안에서 값이 바뀔 수 있으므로
함수의 원형, 함수의 몸체 까지 문장 단위로 확인해야 함.
이러한 문제 때문에
void HappyFunc(const int &ref) { . . .}
=> "함수 내에서 참조자를 통한 값의 변경을 진행하지 않을 경우, 참조자를 const로 선언해서 함수의 원형만 봐도 값의 변형이 이뤄지지 않음을 알 수 있게 한다."
5.반환형이 참조형(Reference Type)인 경우
1) 반환형 참조형, int &num2 = 참조형반환(int &) 형태로 받는 경우
결과: 말그대로 num1의 참조형이 num2라는 뜻이므로 num1과 num2는 같은 변수인 듯이 작동
2)int num2 = 참조형반환(int &) 형태로 받는 경우
int 형으로 만들어진 새로운 변수가 num1를 참조하는 것이므로 num2는 num1과 다른 변수가 됨
3)참조자를 반환하되, 반환형은 기본자료형인 경우
결과는 2와 동일
but
int num2 = RefRetFuncTwo(num1); (0)
int &num2 = RefRetFuncTwo(num1); (x) => 상수를 받는 것과 같으므로
6.잘못된 참조의 반환
int& RetuRefRunc(int n)
{
int num = 20;
num += n;
return num;
}
int &ref = RetuRefFunc(10);
=> 지역변수 num에 저장된 값을 반환하지 않고, num을 참조의 형태로 반환하고 있음
따라서 num에 ref라는 또 하나의 이름이 붙게 되며,
함수가 반환이 되면 정작 지역변수 num은 소멸됨...
주의가 필요!
7.const 참조자의 또 다른 특징
문제점
const int num = 20;
int &ref = num;
ref += 10;
cout << num << endl;
const를 통해 이미 상수화했는데 고치면 컴파일 에러를 일으킨다.
따라서
const int num = 20;
const int &ref = num;
이런 식으로 선언해야 함.
또한, const int &ref = 50;같이 상수 참조가 가능함.
-> 장난해? A.워워, 8을 봐.
8.어떻게 참조자가 상수를 참조하냐고요!
'임시변수'라는 개념 도입.
굳이 어렵게 이런 개념 왜 만들었냐??
이런 케이스 때문
int Adder(const int &num1, const int &num2)
{
return num1 + num2;
}
cout << Adder(3, 4) << endl;
이런 코드 작성할 때 3,4집어넣기 위해 일일히 int n1 = 3; int n2 = 4; Adder(n1,n2) 하면 귀찮으니까...
'LANG > C++' 카테고리의 다른 글
[C++]02-6.C++에서 C언어의 표준함수 호출하기 (0) | 2023.05.11 |
---|---|
[C++]02-5.malloc & free를 대신하는 new &delete (0) | 2023.05.11 |
[C++]02-3.참조자(Reference)의 이해 (0) | 2023.05.11 |
[C++]02-2.새로운 자료형 bool (0) | 2023.05.11 |
[C++]02-1.Chapter 02의 시작에 앞서 (0) | 2023.05.11 |