여태까지 일반 값 타입 변수와 포인터 변수까지 살펴보았다.
- 값 타입 변수: 값 보유
- 포인터 변수: 다른 값의 주소 보유
이번에 살펴볼 변수는 참조형 변수이다.
참조형 변수
참조형은 다른 객체 또는 값의 별칭으로 사용되는 c++ 타입이다. 즉, 변수에 또 다른 이름을 부여한 것이라고 볼 수 있다.
한편, 로우레벨 관점에서 보면 실제 작동 방식은 포인터와 동일하다. (그래서 함수 매개 변수로 전달 될 때 주소 전달 방식으로 동작한다!)
선언
기존에 주소를 나타낼때 &(앰퍼샌드) 기호를 사용하였다. c++에서는 참조를 뜻하는 의미로도 사용하게 된다 (타입을 식별하기 위한 식별자로서 사용). 따라서 참조 변수는 저장하는 변수와 같은 메모리를 참조하게 된다.
자료형& 참조변수명 = 변수명;
int number = 1;
// reference 변수를 수정하면 실제 nubmer 변수를 수정하게 됨!
int& reference = number;
사용 이유
사용성 측면에서 사용한다고 볼 수 있다. 포인터에서 멤버 접근자(->)로 접근하는 불편함을 값 타입으로 정의했던 것 처럼 (.)으로 접근할 수 있다. 또한 함수에 주소를 명시적으로 넘겨주지 않고 내부적으로 알아서 처리해준다.
void RefTest(int& num)
{
}
int main()
{
int temp = 0;
Test(temp);
PtrTest(&temp);
RefTest(temp);
}
한편, 편의성이 좋다는 것이 무조건적인 장점이 될 수는 없다. 포인터는 주소를 넘기니 확실히 원본을 넘긴다는게 명시된다. 하지만, 참조는 값 타입과 문법 자체가 유사하기 때문에 착각하고 마음대로 수정하다 큰 문제로 이어질 수 있다.
이러한 부분은 const를 붙여서 원치 않은 수정을 막아 안정성을 높일 수 있다. (그래서 주로 const와 묶어서 사용되는 편)
void RefTest(const int& num)
{
}
OUT
해당 변수를 참조로 넘겨줬음을 표현하고자 사용한다. (앞서 값 타입과 착각해 마음대로 수정하는 것을 방지하기 위함!)
struct Square
{
int height;
int width;
}
#define OUT
void ChangeHeight(OUT Square& square)
{
square.height = 10;
}
int main()
{
Square square;
square.height = 100;
square.widgth = 100;
ChangeHeight(OUT height);
}
포인터 vs 참조
1. 초기화 여부
포인터와의 또다른 차이는 초기화 여부이다. 참조 타입은 해당 변수의 별칭으로 사용되기 때문에 참조하는 대상이 없으면 안된다.
반면 포인터는 그냥 주소를 의미하기 때문에 대상이 실존하지 않을 수도 있다.
Square square;
Square* pointer;
pointer = □
Square& reference; // 에러 발생! (이니셜라이저 요구)
reference = square;
2. null
포인터의 경우 null 값을 저장할 수 있다. (nullptr)
한편, 참조의 경우 null을 참조할 수 없다.
Square* pointer = nullptr;
int a = nullptr; // 에러 발생! (nullptr)
pointer = □
PrintInfo(pointer); // 실행시 프로그램 뻗음
포인터 <-> 참조
참조형 변수는 결국 특정 변수를 다른 이름으로 칭하는 것이라고 하였다. 포인터는 주소를 가리키는 변수이므로, 포인터가 가리키는 값을 넣어주면 그것을 참조형에 넘겨줄 수 있다!
Square& ref = *pointer; // 포인터가 가리키는 주소의 데이터를 준다!
RefTest(*pointer); // 참조형 매개변수로 받는 함수에 넘겨주기 가능!
포인터 변수의 경우 주소를 가리키는 변수다. 참조형 변수의 경우 데이터를 가지고 있으므로 해당 데이터의 주소 값을 넘겨주기 위해 &를 붙여주면 포인터에 넘겨줄 수 있다!
Square* ptr = &reference; // 참조형 변수가 가리키는 데이터의 주소 넘겨주기
PtrTest(&reference); // 포인터 변수를 매개 변수로 받는 함수에 넘겨주기 가능!
'c++ > 기초' 카테고리의 다른 글
c++ 기초 - 동적 할당 (0) | 2024.02.05 |
---|---|
c++ 기초 - static 변수 및 함수, 정적 지역 객체 (0) | 2024.02.05 |
c++ 기초 - 클래스 (생성자, 소멸자) (0) | 2024.02.04 |
c++ 기초 - 배열 (array) (0) | 2024.02.04 |
c++ 기초 - 포인터 (0) | 2024.02.03 |