C++에서 화살표 연산자(->)란?
C++에는 클래스 멤버에 접근하는 두 가지 연산자가 있습니다. 바로 점 연산자(.)와 화살표 연산자(->)입니다. 두 연산자 모두 클래스의 멤버에 접근한다는 공통점이 있지만, 사용되는 상황이 다릅니다.
C++에서 class, struct, union으로 선언된 타입은 모두 '클래스 타입(class type)'으로 간주됩니다. 따라서 아래 설명은 이 세 가지 타입 모두에 해당합니다.
점 연산자(.)와 화살표 연산자(->)의 차이
a.b는 b가 객체 a(또는 객체를 가리키는 참조)의 멤버일 때만 사용합니다. 즉,a.b에서 a는 항상 실제 객체이거나 객체에 대한 참조여야 합니다.a->b는 본질적으로(*a).b의 축약 표현입니다. 즉, a가 객체를 가리키는 포인터일 때,a->b는 그 포인터가 가리키는 객체의 멤버 b에 접근하는 것입니다.
연산자 오버로딩 관련 주의사항
주목할 점은 점 연산자(.)는 오버로딩할 수 없다는 것입니다. 반면 화살표 연산자(->)는 오버로딩이 가능한 연산자이므로, 개발자가 직접 함수(operator->())를 정의하여 이 연산자가 사용될 때 호출되도록 만들 수 있습니다.
따라서 a가 operator->를 오버로드한 클래스의 객체라면(대표적인 예로 스마트 포인터(smart pointer)와 반복자(iterator)가 있습니다), 그 의미는 해당 클래스 설계자가 구현한 방식에 따라 결정됩니다.
[참고] 참조(reference)는 의미론적으로 객체의 별칭(alias)입니다. 원래는 '포인터에 대한 참조'도 언급해야 하지만, 포인터에 대한 참조(T*&)는 실무에서 거의 사용되지 않기 때문에 오히려 혼란을 줄 수 있다고 판단하여 생략했습니다.
예제 코드
아래 예제는 점 연산자와 화살표 연산자가 동일한 결과를 출력하는 것을 보여줍니다.
#include<iostream>
class A {
public:
int b;
A() { b = 5; }
};
int main() {
A a = A(); // 객체 생성
A* x = &a; // 객체 a의 주소를 포인터 x에 저장
std::cout << "a.b = " << a.b << "
"; // 점 연산자 사용
std::cout << "x->b = " << x->b << "
"; // 화살표 연산자 사용
return 0;
}실행 결과
5 5
정리
핵심을 요약하면 다음과 같습니다.
- 객체 자체나 객체 참조로 멤버에 접근할 때는 점 연산자(.)를 사용합니다.
- 객체를 가리키는 포인터로 멤버에 접근할 때는 화살표 연산자(->)를 사용하며, 이는
(*포인터).멤버와 완전히 동일합니다. - 스마트 포인터나 STL 반복자처럼
->를 오버로드한 타입도 화살표 연산자를 통해 마치 포인터처럼 동작할 수 있습니다.