2. C++ 참조자 ( 래퍼런스 )

wsung·2026년 1월 13일

참조자쓰는법

#include <ionstream>

int main() {
	int a = 3;
    int& another_a = a;
    
    another_a = 5;
    
    std::cout << "a : "<< a << std::end;
    std::cout << "another_a : " << another_a << std::endl;
    
    return 0;
}

=> a : 5
another_a : 5

=> another_a 는 a 의 참조자임
참조자 another_a 는 a 의 또다른 이름 이라고 컴파일러에게 알려줌

int형 변수의 참조자 만들 때
int&

double의 참조자
doubl&

int 같은 포인터 타입의 참조자
int
&

  1. 레퍼런스는 반드시 처음에 누구의 별명이 될 것인지 지정해야 함
    먼저 래퍼런스가 오면 안된다는 뜻
    ex)
int& another_a;
  1. 레퍼런스가 한 번 별명이 되면 절대로 다른 이의 별명이 될 수 없다.
    ex)
int a = 10;
int &another_a = a; // another_a 는 이제 a 의 참조자!

int b = 3;
another_a = b; // a = b 동치
  1. 레퍼런스는 메모리 상에 존재하지 않을 수 도 있다.
  • 포인터는 무조건 메모리를 차지하는 경우가 생기지만
  • 래퍼런스는 대체가능하기 때문에 바꿔치기하면됨 또한 무조건 메모리상에 존재하지 않은건 아니다
#inlclude <iostream>

int change_val(int &p) {
	p = 3;
    
    return 0;
}

int main() {
	int number = 5;
    
    std::cout << number << std::endl;
    change_val(number);
    std:cout << number << std:endl;
}
	int x;
  int& y = x;
  int& z = y;
  • 이런 상황이라면??

참조의 참조를 해야하나??? 틀렸다

  • C++ 문법 상 참조자의 참조자를 만드는 것은 금지되어있음
    => x = y = z가 되어버림

상수에 대한 참조자

#include <iostream>

int main() {
  int &ref = 4;

  std::cout << ref << std::endl;
}

=> 오류가 발생함
? : 참조자가 상수값(리터럴값)을 참조하게되면 ref = 5로 변환할시 4=5라는 오류가 발생함
따라서 상수를 참조하고싶을 땐 const를 사용하여

const int& ref = 4;
int a;
ref = a

a = 4 

이런 식으로 사용함

레퍼런스의 배열과 배열의 레퍼런스

레퍼런스의 배열을 불법(illegal) => 불가능

int a, b;
int& arr[2] = {a, b};

배열은 “각 원소가 실제 메모리에 존재”해야 하는데
👉 레퍼런스는 “별도의 메모리 객체가 아니다”

int arr[3] = {1, 2, 3};
int (&ref)[3] = arr;

❌ 레퍼런스의 배열 (불가능)
int a, b;
int& arr[2] = {a, b}; // ❌

이유 (한 줄)

배열은 실제 메모리 객체의 집합이고
레퍼런스는 메모리 객체가 아니다

핵심만 기억

배열 ⇒ arr + 1 가능해야 함

그러려면 각 원소가 주소를 가져야 함

레퍼런스는 별도 주소를 갖는 객체가 아님

그래서 언어 차원에서 금지

📌 결론

“별명들의 배열”은 만들 수 없다

⭕ 배열의 레퍼런스 (가능)
int arr[3] = {1,2,3};
int (&ref)[3] = arr;

의미

ref는 int[3] 배열 전체의 별명

결과
ref[0] == arr[0]
ref[1] == arr[1]
ref[2] == arr[2]

중요한 규칙
int (&ref)[3]; // 크기 반드시 명시

📌 이유

참조 대상은 실제 배열 객체

배열은 메모리에 존재 → 참조 가능

PART 2️⃣ 레퍼런스를 리턴하는 함수 (위험 구간)
⭕ 값 리턴 (안전)
int function() {
int a = 2;
return a;
}

int b = function(); // 값 복사

✔ a는 사라져도
✔ 값은 복사됐으므로 문제 없음

❌ 지역 변수의 레퍼런스 리턴 (절대 금지)
int& function() {
int a = 2;
return a; // ❌
}

왜 위험?

a는 함수 종료 시 소멸

그런데 그 별명(ref) 을 리턴

본체 없는 별명 → 댕글링 레퍼런스

int b = function(); // 이미 죽은 메모리 접근

📌 결론

지역 변수의 레퍼런스를 리턴하면 안 된다

⭕ 외부 변수의 레퍼런스 리턴 (안전)
int& function(int& a) {
a = 5;
return a;
}

int b = 2;
int c = function(b); // OK

이유

a는 b를 참조

b는 main 끝날 때까지 살아 있음

참조 대상이 여전히 유효

PART 3️⃣ 함수 리턴값을 레퍼런스로 받기
❌ 일반 레퍼런스 (불가능)
int function() {
return 5;
}

int& c = function(); // ❌

이유

함수 리턴값 = 임시 객체

문장 끝나면 사라짐

참조하면 바로 댕글링

컴파일러가 미리 차단

⭕ const 레퍼런스 (예외적으로 가능 ⭐)
const int& c = function(); // ⭕

왜 가능?

C++의 특별 규칙

const 참조는 임시 객체의 수명을 연장한다

내부적으로 이렇게 됨
int temp = function();
const int& c =
temp;

수정 불가 (const)

안전

수명은 c가 살아있는 동안 유지

PART 4️⃣ 이 모든 걸 한 장으로 요약
🚫 절대 하면 안 되는 것

❌ 레퍼런스의 배열
❌ 지역 변수 레퍼런스 리턴
❌ 임시 값에 int& 바인딩

⭕ 안전한 패턴

✔ 배열의 레퍼런스
✔ 외부 변수 레퍼런스 리턴
✔ 임시 값은 const T& 로만 받기

profile
0부터 시작하는 백엔드

0개의 댓글