C++에서 점(.) 연산자와 화살표(->) 연산자는 모두 클래스나 구조체의 멤버에 접근할 때 사용됩니다. 두 연산자의 역할은 비슷하지만, 사용되는 상황이 다릅니다. C++에서 class, struct, union으로 선언된 타입은 모두 "클래스 타입(class type)"으로 간주되므로, 아래의 설명은 이 세 가지 타입 모두에 적용됩니다.
점(.) 연산자와 화살표(->) 연산자의 차이
a.b: b가 객체 a(또는 객체에 대한 참조)의 멤버일 때만 사용됩니다. 즉, a.b에서 a는 항상 실제 객체이거나 객체에 대한 참조여야 합니다.a->b: 본질적으로(*a).b의 축약 표현입니다. a가 객체를 가리키는 포인터라면, a->b는 a가 가리키는 객체의 멤버 b에 접근한다는 의미입니다.
연산자 오버로딩 시 주의 사항
점(.) 연산자는 오버로딩할 수 없지만, 화살표(->) 연산자는 오버로딩이 가능합니다. 따라서 이 연산자가 사용될 때 호출될 사용자 정의 함수(operator->())를 직접 정의할 수 있습니다. 만약 a가 operator->를 오버로딩한 클래스의 객체라면(대표적인 예로 스마트 포인터와 반복자(iterator)가 있습니다), 그 동작 방식은 해당 클래스 설계자가 구현한 내용에 따라 결정됩니다.
참고로, 참조(reference)는 의미론적으로 객체의 별칭(alias)이므로 엄밀히 말하면 "포인터에 대한 참조"라는 경우도 존재합니다. 하지만 포인터에 대한 참조(T*&)는 실무에서 거의 사용되지 않기 때문에, 오히려 혼란을 줄 수 있다고 판단하여 본문에서는 다루지 않았습니다.
예제 코드
#include<iostream>
class A {
public: int b;
A() { b = 5; }
};
int main() {
A a = A();
A* x = &a;
std::cout << "a.b = " << a.b << "\n";
std::cout << "x->b = " << x->b << "\n";
return 0;
}
실행 결과
5 5
정리
객체 자체 또는 객체에 대한 참조로 멤버에 접근할 때는 점(.) 연산자를 사용합니다.
객체를 가리키는 포인터로 멤버에 접근할 때는 화살표(->) 연산자를 사용하며, 이는 포인터를 역참조한 뒤 점 연산자를 적용하는 것과 동일합니다.
화살표 연산자는 오버로딩이 가능하므로, 스마트 포인터나 반복자처럼 포인터처럼 동작하는 사용자 정의 타입을 만들 때 활용됩니다.