본문 바로가기

CS/OOP

C/C++ 포인터와 참조 : 화살표 -> 과 점 . 의 차이

728x90

 C/C++에서 포인터를 쓰다보면 Ver.a()라고 쓰려 하면 IDE가 Ver -> a()로 바꿔주는 경우가 있다. 신경쓰지 않을 수도 있지만 뭐가 다른걸까?

 

간단히 말하면

-> 는 간접

.   는 직접이라고 볼 수 있다.

 

아래 코드를 보자

#include<iostream>

using namespace std;

class Rect {
	int width, height;
public:
	Rect(int x, int y) : width(x), height(y) {}
	int area() { return width * height; }
};

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);	cout.tie(NULL);

	Rect obj(3, 4);
	Rect* foo, * bar, * baz;
	foo = &obj;
	bar = new Rect(5, 6);
	baz = new Rect[2]{ {2, 5}, {3, 6} };

	cout << "obj : " << obj.area() << endl;
	cout << "foo : " << (*foo).area() << endl;
	cout << "bar : " << bar->area() << endl;
	cout << "baz : " << baz[0].area() << endl;
}

 

 

 

 보면 obj는 직접 클래스 타입으로 오브젝트로 선언되었다. 당연히 obj는 직접 접근이 가능하다. 내가 집주인이니까!

그리고 foo bar baz 는 포인터로 선언되었고 foo는 obj를 가리키고 bar, baz는 새로운 객체들을 '가리키게' 되었다. 가리키게 되는 것은 이정표가 되는 것이다. 길을 중앙대학교에서 310관을 가려고 하는데 앞에 310관을 '가리키는' 표지판이 있으면 다들 아 여기로 가면 310이 나오는구나 라고 생각하지 오 도착했다 라고 생각하지 않는다. 

 

그러므로 foo는 저 객체를 가리키고 있는 이정표다. 때문에 ->를 쓴다.

하지만 (*foo) 라고 하면 *foo가 바로 foo가 가리키고 있는 310관이기 때문에 직접연산이 가능하다. 이땐 위 처럼 

bar의 경우 배열 그 자체가 포인터(이정표)가 된다. 

(*foo).area()

foo->area() 는 같은 연산이다. 

 

baz의 경우는 배열이기 때문에 배열은 그 자체가 포인터라는 말을 들어봤을 것이다. 그러므로 별다른 표시 없이 바로 인덱스당 접근이 가능하다.