[C++] 생성자와 소멸자(4-3-2)

서희찬·2021년 5월 19일
0


이어서 진행하겠다.

this 포인터의 이해

맴버함수 내에는 this라는 이름의 포인터를 사용할 수 있는데, 이는 객체 자신을 가리키는 용도로 사용되는 포인터이다. 그럼 간단한 예제를 한번 보자 !

#include <iostream>
#include <cstring>
using namespace std;

class SoSimple
{
private:
    int num;
public:
    SoSimple(int n):num(n)
    {
        cout<<"num="<<num<<", ";
        cout<<"address="<<this<<endl;
    }
    void ShowSimpleDate()
    {
        cout<<num<<endl;
    }
    SoSimple * GetThisPointer()
    {
        return this;
    }
};

int main(void)
{
    SoSimple sim1(100);
    SoSimple * ptr1 = sim1.GetThisPointer(); // sim1 객체의 주소 값 저장
    cout<<ptr1<<", ";
    ptr1->ShowSimpleDate();

    SoSimple sim2(200);
    SoSimple * ptr2 = sim2.GetThisPointer(); // sim1 객체의 주소 값 저장
    cout<<ptr2<<", ";
    ptr2->ShowSimpleDate();
    
}

이해를하자!
우선, this를 반환하는데 이는 이 문장을 실행하는 객체의 포인터를 반환하라는 의미이다!
그래서 반환형도 SoSimple* 형으로 선언되어 있다.
객체 sim1에 의해 반환된 this를 ptr1 에 저장하는데 이 때 this 는 SoSimple의 포인터 이므로 SoSimple형 포인터 변수에 저장해야한다.
그렇게하여 ptr1에 저장된 주소 값을 출력하는것을 보여준다.

이렇듯 this는 객체자신의 주소 값을 의미한다는 사실을 확인 및 이해했을 것이다.
이렇듯 this포인터는 그 주소 값과 자료형이 정해져 있지 않은 포인터이다 !

this 포인터의 활용

이러한 this 포인터는 제법 유용하게 사용된다!
이에 대한 설명에 앞서 먼저 다음 클래스를 관찰해보자 !

class ThisClass
{
private: 
	int num; // 207 save 
public:
	void ThisFunc(int num)
    	{
	        this->num = 207;
            	num = 105;  매개변수 의 값을 105로 변경 
	} 

이를 보면 ThisFunc 함수의 매개변수 이름은 num인데!!
이 이름은 맴버변수의 이름과 동일하다!
그렇기에 ThisFunc 함수 내에서의 num은 매개변수 num을 의미하게된다.

따라서 변수의 이름만 참조하는 방법으로는 ThisFunc 함수내에서 맴버변수 num에 접근이 불가능하다.

그러나!!
This포인터 배열을 활용하면 가능하다!!!

this -> num = 207;

위 문장에서 this는 객체를 참조하는 포인터이다.
그럼 객체 참조 포인터를 가지고 접근하는 변수 num은 맴버변수겠냐!
아니면 지역변수이겠느냐!!!
당연빠따로 객체의 포인터가지고 지역변수에 접근은 불가능하므로, 맴버변수이다!

그러므로!
this를 활용하여 매개변수의 이름을 맴버변수의 이름과 달리하기위해 고민할 필요가 없다!!!!

다음예제를 한번 보자 .

#include <iostream>
using namespace std;

class TwoNumber
{
private:
   int num1;
   int num2;
public:
   TwoNumber(int num1, int num2)
   {
       this->num1 = num1;
       this->num2 = num2;
   }
//    TwoNumber(int num1, int num2):num1(num1),num2(num2)
//    {
//
//    }
   void ShowTwoNumber() const
   {
       cout<<this->num1<<endl;
       cout<<this->num2<<endl;
   }
};

int main(void)
{
   TwoNumber two(2,4);
   two.ShowTwoNumber();
   return 0;
}

this를 이용해서 매개변수 num1,num2를 통해서 전달된 값이 맴버변수 num1,num2에 저장된다.

맴버 이니셜라이저에서는 this 포인터를 사용할 수 없다.
대신에 저장하는 변수는 맴버변수로, 저장되는 값은 ()소괄호 안의 변수 및 상수는 매개변수로 인식하기 때문에 위의 주석처리한 형태의 문장 구성이 가능하다 !

ShowTwoNumber 에서는 굳이 this를 사용하여 보일필요 없지만 !
여기에서는 맴버변수에 접근함을 명확히 보여주기 위해 표시하였다.

변수의 이름을 짓는 것은 의외로 신경이 쓰이는 일이다!!!
특히 유사한 성격을 지니는 두 변수의 이름을 구별 되게 짓는 것은 고민스럽기까지 하기에 !
맴버변수와 매개변수의 이름을 동일하게 하고
this포인터를 이용해서 이 둘을 구분하는 것을 좋아하는 프로그래머들도 꽤 있다 !

Self-Reference의 반환

Self-Reference란 객체 자신을 참조할 수 있는 참조자를 의미한다!
우리는 this포인터를 이용해서, 객체가 자신의 참조에 사용할 수 있는 참조자의 반환문을 구성하는것을 배웠다.

그럼 이와 관련해서 예제 하나를 살펴보자!

#include <iostream>
using namespace std;

class SelfRef
{
private:
    int num;
public:
    SelfRef(int n):num(n)
    {
        cout<<"객체 생성"<<endl;
    }
    SelfRef& Adder(int n)
    {
        num+=n;
        return *this;
    }
    SelfRef& ShowTwoNumber()
    {
        cout<<num<<endl;
        return *this;
    }
};

int main(void)
{
    SelfRef obj(3);
    SelfRef &ref= obj.Adder(2);
    
    obj.ShowTwoNumber();
    ref.ShowTwoNumber();
    
    ref.Adder(1).ShowTwoNumber().Adder(2).ShowTwoNumber();
    return 0;
    
}


함수 Adder에서는 선언된 반환형과 반환의 내용을 함께 살펴야한다.
반화느이 내용은 *this인데, 이는 문장을 실행하는 객체 자신의 포인터가 아닌, 객체 자신을 반환하겠다는 의미가 된다.
그런데 반환형이 참조형 SelfRef&으로 선언되었다.
따라서 !
객체 자신을 참조할 수 있는 "참조의 정보"가 반환된다.

그 이후 마찬가지로 객체 자신을참조할 수 있는 참조 값을 반환하도록 정의 되었다.

SelfRef &ref = obj.Adder(2);

obj의 Adder함수를 호출하였는데, 이는 객체 자신의 참조 값을 반환한다.
따라서 객체 obj의 참조 값으 반환하므로 참조자 ref는 객체 obj를 참조하게 된다.

그 후
객체 ref의 adder함수가 호출 되어 참조 값이 반환되고 이를 다시 ShowTwoNuber 함수를 호출한다.

이는 두 함수 Adder,ShowTwoNuber가 객체의 참조 값을 반환하기 때문에 구성이 가능한 문장이다.

참조의 정보(참조 값)에 대한 이해

참조 값이 무엇인지 아는가?
다음 코드를 보자

int main(void)
{
	int num = 7;
	int &ref = num; // 무엇이 전달된다고 해야할까?
    

두번째 대입연산에 의해 num을 참조자 ref가 참조하게 된다.

그렇다면 !
대입연산의 과정에서 참조자 ref에 무엇이 전달된다고 해야할까?
한가지 ! 확실한 것은 num에 저장된 정수 값은 아니다!
그래서 대입연산에 어울리게 다음과 같이 표현하기도 한다.

"변수 num을 참조할 수 있는 참조의 정보가 전닿된다."

즉!

"변수num을 참조할 수 있는 참조 값이 참조자 ref에 전달되어, ref가 변수 num을 참조하게 된다."

profile
Carnegie Mellon University Robotics Institute | Research Associate | Developing For Our Lives, 세상에 기여하는 삶을 살고자 개발하고 있습니다

0개의 댓글