C 언어에서는 표현식의 왼쪽(좌변)에 함수 이름을 사용할 수 없습니다. 반면 C++에서는 참조(reference)를 반환하는 함수를 활용하면 함수 호출 결과를 대입문의 왼쪽에 놓을 수 있습니다.
C++ 함수는 포인터를 반환하는 방식과 유사하게 참조를 반환할 수 있습니다. 함수가 참조를 반환하면 사실상 반환 값에 대한 암시적 포인터를 돌려주는 것이므로, 해당 함수가 마치 변수처럼 동작하여 대입문의 좌변에 위치할 수 있게 됩니다.
참조 반환 예제
다음은 배열의 특정 요소에 대한 참조를 반환하는 간단한 C++ 프로그램입니다.
#include <iostream>
#include <ctime>
using namespace std;
double vals[] = {10.1, 12.6, 33.1, 24.1, 50.0};
double& setValues(int i) {
return vals[i]; // i번째 요소에 대한 참조를 반환
}
// 위에서 정의한 함수를 호출하는 main 함수
int main() {
cout << "Value before change" << endl;
for (int i = 0; i < 5; i++) {
cout << "vals[" << i << "] = ";
cout << vals[i] << endl;
}
setValues(1) = 20.23; // 2번째 요소 변경
setValues(3) = 70.8; // 4번째 요소 변경
cout << "Value after change" << endl;
for (int i = 0; i < 5; i++) {
cout << "vals[" << i << "] = ";
cout << vals[i] << endl;
}
return 0;
}실행 결과
Value before change vals[0] = 10.1 vals[1] = 12.6 vals[2] = 33.1 vals[3] = 24.1 vals[4] = 50 Value after change vals[0] = 10.1 vals[1] = 20.23 vals[2] = 33.1 vals[3] = 70.8 vals[4] = 50
실행 결과에서 볼 수 있듯이 setValues(1) = 20.23;처럼 함수 호출 자체가 대입의 대상이 되어 배열 요소의 값이 성공적으로 변경되었습니다. 이는 함수가 실제 메모리 위치에 대한 참조를 반환하기 때문입니다.
참조 반환 시 주의사항
참조를 반환할 때 가장 중요한 점은 반환되는 객체가 유효 범위(scope)를 벗어나지 않도록 하는 것입니다. 지역 변수에 대한 참조를 반환하는 것은 컴파일 오류(또는 미정의 동작)를 유발하므로 허용되지 않습니다. 대신 정적(static) 변수에 대한 참조는 프로그램 종료까지 유지되므로 안전하게 반환할 수 있습니다.
int& func() {
int q;
//! return q; // 컴파일 타임 오류 - 지역 변수 참조 반환 불가
static int x;
return x; // 안전함 - x는 이 범위 밖에서도 생존
}정리하면, C++에서 참조 반환 기능을 활용하면 함수를 좌변에 사용할 수 있지만, 반드시 함수가 종료된 후에도 유효한 객체(전역 변수, 정적 변수 등)를 반환해야 한다는 점을 기억해야 합니다.