SW/C++

C++11 : 값, 참조에 의한 호출에 대해 알아볼까요?

얇은생각 2018. 12. 27. 12:30
반응형

값에 의한 호출 방식

값에 의한 호출 방식은 값을 복사하는 개념과 같은 맥락입니다. 다음의 예제를 보겠습니다.


#include <iostream>
using namespace std;
 
int main(void)
{
    int value = 3;
    int i = value;
    i = 33;
    cout << "value = " << value << endl;
    cout << "i = " << i << endl;
    return 0;
}
cs


값에 의한 호출 방식은 변수를 복사하는 예와 같은 개념입니다. 즉 함수를 호출할 떄 전달하는 인자를 해당 함수의 매개 변수로 복사합니다. 따라서 함수 안에서 매개변수의 값을 변겨해도 함수를 호출할 때 전달한 인자에는 영향을 줄 수 없습니다.


#include <iostream>
using namespace std;
 
class Restaurant
{
public
    int Steak; // 스테이크 가격
};
 
class Chulsoo
{
public:
    int Eat(int);
};
 
// 철수가 먹은 스테이크 가격을 받아서 반환하는 함수 정의
int Chulsoo::Eat(int SteakNum) 
{
    SteakNum = 10000// 철수가 10,000원 짜리 스테이크를 먹었다고 거짓말
    cout << "철수는 먹는다" << endl;
    return SteakNum;
}
 
int main(void)
{
    Chulsoo chulsoo; 
    Restaurant restaurant; 
 
    restaurant.Steak = 20000// 레스토랑에서 철수에게 준 스테이크는 20000원
    cout << "철수는 " << chulsoo.Eat(restaurant.Steak) << "원 짜리 스테이크를 먹었다고 거짓말을 했다." << endl;
    cout << "레스토랑은 철수가 " << restaurant.Steak << "원 짜리 스테이크를 먹었다고 알고 있다." << endl;
 
    return 0;
}
cs


위 처럼 코드를 짠다면 철수의 거짓말은 통하지 않습니다. 값에 의한 호출방식은 함수를 호출할 때 전달한 인자를 함수의 매개변수로 복사합니다. 따라서 두 변수가 사용하는 메모리 공간이 서로 다르므로, 함수에서 매개변수의 값을 변경하더라도 호출할 때 전달한 인자에는 영향을 미치지 않습니다.



참조에 의한 호출 방식

참조에 의한 호출 방식은 앞서 설명한 값에 의한 호출 방식과는 다른 개념입니다. 참조에 의한 호출 방식은 참조자를 이용합니다. 이는 곧 주솟값을 이용한다는 의미와 같아서 주소에 의한 호출(call by addresss)과 유사합니다. 그러나 주로 사용하는 참조에 의한 호출 방식에 집중해서 설명하겠습니다.


다음 예제를 통해 참조자에 대해 알아봅시다.


#include <iostream>
using namespace std;
 
int main(void)
{
    int value1 = 1, value2 = 11;
    int &refvalue1 = value1;
    refvalue1 = 22;
    refvalue1 = value2;
    value2 = refvalue1;
 
    cout << "value1 = " << value1 << endl;
    cout << "value2 = " << value2 << endl;
    cout << "refvalue1 = " << refvalue1 << endl;
}
cs


이러한 참조자를 함수의 매개변수로 지정하면 참조에 의한 호출 방식을 구현할 수 있습니다. 즉 함수를 선언할 때 매개변수를 참조자로 선언하면 해당 함수를 호출할 때 전달받은 인자를 참조할 수 있습니다. 여기서 참조는 값에 의한 호출 방식에서 복사와는 전혀 다른 개념입니다.


참조자는 선언과 동시에 초기화하지 않으면 오류가 발생합니다. 이러한 특징에 따라 참조에 의한 호출 방식을 사용하면 함수를 호출할 때 전달한 인자로 참조자 매개변수를 초기화합니다.


함수의 매개변수가 해당 함수를 호출할 때 전달한 인자를 참조한다는 것은 함수 내부에서 함수 외부의 변수에 접근할 수 있다는 의미입니다. 


#include <iostream>
using namespace std;
 
class Restaurant
{
public
    int Steak; 
};
 
class Chulsoo
{
public:
    int Eat(int&);
};
 
int Chulsoo::Eat(int& SteakNum) 
{
    SteakNum = 10000// 철수가 10,000원 짜리 스테이크를 먹었다고 거짓말
    cout << "철수는 먹는다" << endl;
    return SteakNum;
}
 
int main(void)
{
    Chulsoo chulsoo; 
    Restaurant restaurant; 
    restaurant.Steak = 20000// 레스토랑에서 철수에게 준 스테이크는 20,000원
    cout << "철수는 " << chulsoo.Eat(restaurant.Steak) << "원 짜리 스테이크를 먹었다고 거짓말을 했다." << endl;
    cout << "레스토랑은 철수가 " << restaurant.Steak << "원 짜리 스테이크를 먹었다고 알고 있다." << endl;
    return 0;
}
cs


값에 의한 호출 예제와 비교한다면 유일하게 달라진 행은 13행과 16행 뿐입니다.실행 결과를 보면 철수의 거짓말이 통하는 것을 볼 수 있습니다. 함수 내부에서 함수 외부의 변수에 접근할 수 있는 참조에 의한 호출 방식을 ㅣ용하여 실제 레스토랑의 스테이크 가격을 만원으로 속이는 데 성공하였습니다.


참조에 의한 호출방식은 값에 의한 호출 방식과는 달리, 함수 내부에서 함수 외부의 값을 변경할 수 있습니다. 이는 C++에서 상당히 중요한 개념입니다.

반응형