본문 바로가기
프로그래밍/C++

C++ this 포인터?? 그럼 *this 는 뭐지?

by Hwan2 2019. 2. 22.
728x90
반응형

※ *this에 대한 설명은 맨 아래에 설명하고 있습니다. 맨 아래만 보면 이해가 잘 가지 않을테니

처음부터 차근차근 읽어주시기 바랍니다.^^

또한 설명 중 C++의 '참조자'와 포인터의 '값의 참조' 부분이 햇갈릴 수 있으니 유의해 주세요!!

 

 

 

C++ 에서 this란 자기 자신을 나타내는 말입니다.

 

즉 Class A a; 라는 객체가 있고 이 a의 주소값은 0x10 이라고 가정한다면

 

a 객체에서의 this는 0x10이라는 뜻입니다. 

 

일단 코드로 확인해 보자면

 

#include <iostream>

using namespace std;

class A {
    int num;
public:
    void print_This() {
        cout << "Class A의 this 주소 : " << this << endl;
    }

    A * return_A() {
        return this;
    }
};

int main(void) {

    A a;

    cout << "a의 주소값 : " << &a << endl;
    a.print_This();

    cout << "a.return_A() : " << a.return_A() << endl;

    return 0;
}
 

 

객채 a의 주소값이 모두 같은걸 알 수 있습니다.

 

즉, this는 자기 자신을 가르키는 키워드 입니다.

 

this는 주로 맴버 변수를 초기화 할때 사용됩니다.

 

#include <iostream>

using namespace std;

class A {
    int num;
public:
     
    A(int num) {
        this->num = num;
    }

    int get_Num() {
        return num;
    }
};

int main(void) {

    A a(10);

    cout << a.get_Num() << endl;
    return 0;
}
 

 

즉 this는 자기 자신의 객체를 가르키는 것입니다. 따라서 this->num은 매개변수A(int num)를 가르키는 것이 아닌!! 맴버변수를 가리키는 것입니다.

 

혹은 코드가 길어지고 객체의 활용도가 높아질 수록 자기 자신을 반환해야 할 일이 생깁니다.

 

그럴때 return this를 이용하면 됩니다.

 

 

 

그렇다면 '*this'는 뭘까요??

 

저도 처음엔 많이 헤맸는데 지금은 이해를 했습니다.

 

int main(void) {

    int num_1 = 111;
    int *p = &num_1;

    int &ref1 = *p;
    int *(&ref2) = p;

     
    printf("%d\n", &ref1);  //ref1의 주소 값(참조자)
    printf("%d\n", ref2);   //ref2가 가르키는 주소 값(참조 포인터)
    printf("%d\n", p);      //p가 가르키는 주소 값
    printf("%d\n", &num_1); //num_1의 주소 값
    printf("%d\n", &ref2);  //ref2의 주소 값


    return 0;
}
 

 

위 코드를 보면 

 

int &ref1 = *p;

int *(&ref2) = p;

 

이 부분이 있습니다.

 

언듯 보면 이해하기 어렵지만 알고보면 쉽습니다.

 

*p는 출력하면 111이 나오죠. 이 것은 *p가 가르키는 값을 참조하기 때문입니다.(포인터의 참조 입니다.)

 

그럼 int &ref1 = *p는 int &ref1 = num_1; 으로 생각할 수 있는 겁니다.

 

int *(&ref2) = p; 는??? 이건 p가 가르키는 주소 값을 받는 상황임으로 당연히

 

포인터로 받아야 하지만 ref2는 참조값으로 저런식으로 받는것도 가능합니다.

 

단!! ref2는 참조변수지만 포인터로 전달 받기 때문에 별도의 포인터 주소 값을 지닙니다.

(마지막 출력 값을 보면 ref2의 주소값이 다른걸 알 수 있습니다.)

 

 

this와 *this도 같은 시각으로 보면 쉽습니다.

 

#include<iostream>

using namespace std;

class A {
public:
    int num = 10;

    void print_This() {
        cout << this << endl;
    }

    A& return_This() {
        return *this;
    }
};


int main(void) {

    A a;

    a.print_This();

    A &ref = a.return_This();

    ref.print_This();

    printf("a의 주소 값 %d\n", &a);
    printf("ref의 주소 값 %d\n", &ref);

    return 0;
}​

 

 

 

이런식이 됩니다.

 

this는 자기자신을 가르키는 키워드 이고.

 

*this는 자기자신의 값(맴버변수, 함수 등....)을 나타내는 키워드. 

즉, 포인터의 참조개념 라고 생각하시면 좀 더 이해하기 수월할 것 같습니다.

 

 

A &ref = a.return_This(); 부분을 A ref = a.return_This() 형태로 바꿔도 상관 없습니다.

 

int n1 = *p; 가 되듯이 A temp = a.return_This(); 의 형태도 가능 합니다. 

(단, A& temp가 아닌 A temp형태로 받으면 복사생성자에 의해 temp와 a는 서로 다른 주소값을 갖게 됩니다.!!)

 

 

return_This() 함수의 return 값이 A&가 아니라 A라고 한다면  

 

int n1 = num_1; 이 되듯 A temp = a.return_This(); 의 형태도 가능 합니다. 

(단, 이 부분도 마찬가지로 복사생성자의 호출로 이어져 temp와 a.return_This()는 서로 다른 주소 값을 지닙니다.)

 

즉, 복사생성자의 불필요한 호출로 인한 프로그램 성능의 저하가 오는걸 고려하지 않는 이상,

굳이 *this를 참조자로 받지 않아도 된다는 소리입니다.

(이 경우도 솔직히 애매한대 보통 'return this' 를 사용한다면 새로운 객체를 반환하거나 기존 객체를 그대로 사용하는 등....

상황이 너무나 많습니다. 따라서 그냥 상황에 맞게 잘 고려해서 사용하시기 바랍니다.)

 

 

정리하자면......

 

this는 자기 자신을 가르키고 있는 포인터 개념이고

*this는 자기 자신의 클래스 그 자체라고 보시면 됩니다.

 

따라서 

 

A& return_This() {
        return *this;
}        //OK!!    (가르키는 자기자신(객채)라서 참조 가능)

A return_This() {
        return *this;
}        //OK!!    (복사 생성자에 의해 주소값 다름)

A& return_This() {
        return this;
}        //error    (주소 값에 대한 참조는 안되기 때문)

A * return_This() {
        return this;
}        //OK!!    (주소값이 반환되므로)

A return_This() {
        return this;
}        //error    (포인터를 일반적인 변수로 받으면 안되기 때문)​

 

앞서 설명한 int &ref = *p; 부분과 return *this 부분을 잘 비교하면서 보시면 이해하실거라 믿습니다.!!

 

 

P.S

그냥 두놈다 같은 기능을 합니다. 보는 시각에 따라 차이점을 둔 것 뿐......

반응형

댓글


스킨편집 -> html 편집에서