this란 멤버함수를 호출한 객체의 주소를 저장하는 상수포인터이다.
객체가 생성될 때 멤버변수와 멤버함수가 모두 포함된다고 배워왔다. 하지만 이것은 이해를 돕기 위해 설명한 것이지 실제로는 그렇지 않다. 객체를 생성할 때에는 멤버변수들은 각각 할당되지만 멤버함수는 모든 객체가 공유하기 된다. 그러므로 클래스의 멤버함수 호출 시 어떤 객체가 멤버함수를 호출했는지 구별할 수 있도록 호출한 객체를 함수로 전달한다. 이때 함수는 이 객체를 받기 위한 포인터를 매개변수로 가지게 되는데 이를 this라 한다.
모든 클래스의 멤버함수는 this라는 상수포인터를 매개변수로 보이지 않게 가지고 있다. this는 멤버함수를 호출한 객체 자신의 주소를 저장하는 포인터이며 이를 자기참조포인터라 한다. 다음의 예제를 확인해보고 자기참조포인터의 뜻도 유추해보자.
#include <iostream> using namespace std; class TEST { public: TEST* getthis() { return this; } }; int main() { TEST* t; t=new TEST; cout<<"this의값은"<<t->getthis()<<endl; cout<<"동적할당된객체의주소는"<<t<<endl; return 0; } |
위의 예제를 실행시키면 getthis의 리턴 값과 동적할당 된 객체의 주소값은 같음을 쉽게 확인 할 수 있다. 이때 객체를 동적할당을 한 것을 확인 할 수 있는데 이는 동적할당 한 객체의 주소를 얻기 위함이다.
위의 예제에서도 볼 수 있듯, this는 호출하는 객체 자신을 참조하는 포인터이며 이를 사용하는 경우는 객체의 멤버변수를 가리킬 때 사용한다. 만약에 생성자나 함수의 매개변수가 멤버변수의 이름과 동일할 때는 다음과 같은 문제가 발생하게 된다. 예제를 확인해보자.
#include <iostream> using namespace std; class RET { int num1, num2; int getnum1() { return num1; } int getnum2() { return num2; } public: RET(int num1, int num2) { num1=num1; num2=num2; } void display() { cout<<getnum1()<<endl; cout<<getnum2()<<endl; } }; int main() { RET r1(2,5); r1.display(); return 0; } |
위의 예제를 실행해보면 두 값 모두 쓰레기 값으로 출력되는 것을 확인 할 수 있다. 이는 인수전달생성자 부분에서 멤버변수의 값을 초기화 하는 구문이 잘못되었음을 보여준다. 멤버변수인 num1과 num2가 초기화 되지 않았기 때문에 쓰레기 값이 나오는 것이다. 이 예제는 this를 사용하면 아주 쉽게 해결 할 수 있다.
RET(int num1, int num2) { num1=num1; num2=num2; } |
=> |
RET(int num1, int num2) { this->num1=num1; this->num2=num2; } |
즉, this의 사용 용도는 클래스 안의 생성자나 멤버함수의 매개변수로 멤버변수에 대입 할 때 멤버함수를 표시하기 위함이다.