2019년 5월 13일 월요일

C++ Reference

C++ reference에 대해서 잘못 알고있는 부분과 자세히 몰랐던 부분이 있어서
이 부분에 대해 공부한 후 포스팅을 해보려고 한다.





- Reference

C++에서는 Reference(&)라는 변수타입이 제공된다.
간단히 말해서 별명을 붙혀주는 기능이다.


int &ret = dp[curr];
cs
알고리즘 포스팅중 dp - top down으로 구현한 코드에 대부분 등장하는 코드이다.


ret = 30;
printf("dp[curr] : %d\n",dp[curr]);         // 30
cs
dp[curr]ret이라는 별명을 붙혀주었고 이 값을 30으로 변경했기 때문에  30으로 출력이 된다.





- Reference type

이러한 Reference는 세 가지 종류의 참조형을 제공한다.

  •  non-const value
  •  const value
  •  r-value (using &&)

int a = 10;
int& ref1 = a;            // okay [non-const l-value]
const int b = 20;
int& ref2_1 = b;        // not okay
const int& ref2_2 = b;    // okay [const l-value]
int&& ref3 = 30;        // okay [r-value]
cs

l-value, r-value에 대해서는 다음 포스팅에서 다뤄보도록 하겠다.





- Pass by reference

reference를 함수 인자부분에 사용하는 것을 말한다.
인자 변수가 복사되어 생성되지 않기 때문에 Pass by value에 비해 속도가 빠르다.




int Square(const int& input) {
    int ret = input * input;
    return ret;
}
cs
const 키워드를 붙여서 함수 내부에 변경이 없도록 사용하는 경우가 많다.





- Return by Reference

이 부분은 조심해서 사용해야 한다.
reference를 함수 반환값으로 사용하는 것을 말한다.
이 기능을 수행할 때는 reference의 원본이 메모리 상에 유지되어야 한다. 
(당연한 말이지만 무심코 이 원칙을 지키지 않을 수 있다.)


#include <bits/stdc++.h>
using namespace std;
int& function() {
    int val = 10
    return val;
}
int& function2() {
    int val2 = 20;
    return val2;
}
int main(){
    int& ref = function(); 
    int& ref2 = function2();
    cout << ref << endl;        // output : 20
}
cs
위의 예시에서는 10이 출력될것 처럼 보이지만 20이 출력이된다.



처음 function()이 호출 되면 다음과 같은 주소에 값이 들어갈 것이다.



 그 다음 function() 함수가 종료되면 val변수는 사라졌지만 여전히 같은 주소를 지니게 된다.



 function2() 함수가 호출되면 ref, ref2변수 모두 val2의 주소값을 가지게된다.



결국 마지막에는 이런 결과를 얻게된다.



위의 과정은 심각한 오류를 초래할 수 있으므로 사용하지 말도록 하자.

아니면 static 변수로 선언하여 이 문제를 해결할 수 있다.

static 변수는 global 변수와 같이 data영역에 할당이 되고 
함수, 함수의 지역변수는 heap영역에 메모리 할당과 해제가 이루어 진다.



static 변수는 선언과 동시에 data영역에 존재해 함수 호출 후에도 남아있게 되기때문에 
위의 문제를 해결할 수 있다.


#include <bits/stdc++.h>
using namespace std;
int& function() {
    static int val = 10
    return val;
}
int& function2() {
    static int val2 = 20;
    return val2;
}
int main(){
    int& ref = function(); 
    int& ref2 = function2();
    cout << ref << endl;        // output : 10
}
cs




[출처]
https://boycoding.tistory.com/207 /
https://snbosoft.tistory.com/entry/%EC%A0%9C2%EC%9E%A5-C-%EA%B8%B0%EB%B3%B8-Reference%EB%A5%BC-return%ED%95%98%EB%8A%94-%ED%95%A8%EC%88%98%EC%9D%98-%EC%A0%95%EC%9D%98 /
https://www.tutorialspoint.com/cplusplus/returning_values_by_reference.htm /