참조형
참조형은 특정 인스턴스의 주소를 참조하는 자료형이라고 할 수 있다. C의 포인터와 비슷하다.
특이한 점은 선언과 동시에 초기화를 해야하며, 이후 값을 변경할 수 없다는 것이다.
참조형이 메모리에서 직접 참조중인 데이터는 변경이 가능하겠지만, 참조형 자체가 가진 메모리 주소값은 변경이 안된다.
(참조 메모리가 불변이라는 점에서 진정한 의미의 Call by reference라고 할 수 있다.)
int main()
{
int data(10);
// 참조형
int& ref = data;
ref = 20;
std::cout << data << std::endl;
// 포인터 주소 연산자 및 역참조 연산자
int* pData = &data;
*pData = 30;
std::cout << data << std::endl;
return 0;
}
참조형은 식별자에 앰퍼센드(&)를 붙여서 선언한다. 위의 코드에서 참조형 ref는 data를 참조하게 된다.
ref는 data를 참조하고 있으므로, ref를 직접 수정하게되면 ref가 참조하고 있는 data의 값이 바뀌게 된다.
(ref 자체는 바뀌지 않는다는 점을 제외하고는 포인터 개념과 똑같음)
디버그 모드에서 메모리를 한번 까보자
메모리 주소 뒷 4자리 F8C4와 F8E4는 각각 참조형 ref와 포인터 pData의 주소이다.
참조형 ref의 메모리 주소인 F8C4는 20(1e)이 기록되어있는 F8A4 메모리를 참조중이며,
포인터 pData의 메모리 주소인 F8E4 또한 F8A4 메모리를 참조하고 있다.
즉 둘은 역할이 똑같다.
단 참조형의 경우, 내부에 담긴 주소값 자체는 지울수가 없다. ref에 직접 0을 할당하면 data가 0이 될 뿐이다.
반면에 포인터에 pData에 0을 할당한다면 pData가 참조하는 메모리의 주소가 0이 될 것이다.
이런 현상을 이용하면 매개변수를 받는 함수를 비교적 간단히 구성할 수 있다.
아래는 참조자를 이용하여 swap 함수를 쉽고 편하게 구현한 것이다.
#include <iostream>
#include <cstring>
void swap(int& a, int& b)
{
int tmp = a;
a = b;
b = tmp;
}
int main()
{
int x = 50, y = 100;
std::cout << x << " " << y << std::endl;
swap(x, y);
std::cout << x << " " << y << std::endl;
return 0;
}
swap 함수에서 아예 참조형을 매개변수로 받고있으므로, swap 함수에 x와 y를 별도의 포인터 처리 없이 매개변수로 넘겨주기만 하면 x와 y값이 정상적으로 스왑될 것이다.
'C, C++' 카테고리의 다른 글
C++) 범위 기반 for문 (0) | 2024.01.19 |
---|---|
C++) 임시 객체와 r-value 참조 (0) | 2024.01.19 |
C++) 메모리 동적 할당 (0) | 2024.01.17 |
C++) 변수 선언 및 정의 (0) | 2024.01.17 |
C++) 리다이렉션 연산자 및 std::cout (콘솔 출력) (0) | 2024.01.17 |