C++에서 this 포인터 사용

Muhammad Husnain 2023년10월12일
  1. C++에서 this 포인터 사용
  2. C++에서 this*this의 차이점
C++에서 this 포인터 사용

이 튜토리얼에서는 먼저 this 포인터의 개념을 이해할 것입니다.

그런 다음 예제를 통해 사용법을 보여드리겠습니다. 마지막으로 this*this와 어떻게 다른지 살펴보겠습니다.

C++에서 this 포인터 사용

this 포인터는 비정적 클래스 멤버 함수 범위에서 호출 개체를 참조하거나 가리키는 암시적으로 사용 가능한 포인터입니다. 정의로 이해하지 못했다면 개념을 이해하기 위해 몇 가지 기본 사항을 살펴보겠습니다.

우리는 모든 비정적 데이터 멤버가 각 개체에 대해 별도의 복사본을 가지고 있다는 것을 알고 있습니다. 그러나 멤버 함수 코드는 모든 개체에서 공유됩니다.

동일한 클래스의 모든 객체는 호출해야 할 때 코드 세그먼트에서 동일한 함수 정의에 액세스합니다. 컴파일러는 이 특정 호출 개체에 특정한 올바른 데이터 멤버에 액세스하거나 업데이트하기 위해 호출 개체(현재 멤버 함수를 호출하는 사람) 정보를 알아야 합니다.

따라서 함수 정의가 동일하다면 컴파일러는 호출 객체 정보를 어떻게 얻습니까?

간단한 대답은 프로그램을 컴파일하는 동안 컴파일러가 멤버 함수에 숨겨진 암시적 포인터 매개변수를 자동으로 추가한다는 것입니다. 이 암시적 포인터를 this 포인터라고 합니다.

멤버 함수가 특정 클래스 개체를 통해 호출될 때마다 호출 개체는 this 포인터에 대한 숨겨진 인수로 자동으로 제공됩니다. 이제 컴파일러는 이 포인터를 사용하여 호출 개체와 관련된 올바른 데이터 멤버에 액세스하거나 수정할 수 있습니다.

메모
this 포인터는 클래스의 정적 멤버와 함께 필요하지 않습니다. 이러한 멤버(함수 및 데이터 멤버)는 모든 객체에서 공유되기 때문입니다.

정적 멤버에 대한 업데이트 또는 액세스는 특정 개체에 국한되지 않습니다. 클래스의 객체를 생성하지 않고도 이러한 멤버에 액세스할 수도 있습니다.

따라서 컴파일러는 이러한 멤버와 함께 this 연산자를 사용하지 않습니다.

컴파일러가 암시적으로 this 포인터를 사용한다고 말하는 이유와 편리한 경우를 이해하기 위해 코드 예제를 살펴보겠습니다.

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

class Person {
 private:
  string Name;

 public:
  Person(string Name) {
    this->Name = Name;  // this->Name is the private member for this object
  }
  void PrintName() { cout << this->Name << endl; }
  void PrintName1() { cout << Name << endl; }
};
int main() {
  Person P("Alexa");
  P.PrintName();
  P.PrintName1();
  return 0;
}

위의 코드 예제는 개인 데이터 멤버 Name을 인쇄하기 위해 두 개의 다른 멤버 함수가 있는 Person 클래스를 정의합니다. main() 함수의 첫 번째 명령문은 Person 객체를 생성하고 Alexa를 생성자에 대한 인수로 전달합니다.

이제 생성자의 this->Name은 컴파일러가 로컬 매개변수 Name과 개인 데이터 멤버 Name을 구별하는 데 도움이 됩니다.

main()의 후속 코드는 P를 통해 printName()printName1()을 호출합니다(즉, P는 호출자 객체가 됨).

출력:

Alexa
Alexa

두 함수의 출력은 동일합니다. 이는 컴파일러가 PrintName1()에서 이->이름으로 암시적으로 앞에 두기 때문입니다.

C++에서 this*this의 차이점

지금까지 우리는 this가 객체에 대한 포인터라는 개념을 분명히 했습니다. Person 유형의 obj에 대해 thisPerson* 유형입니다.

기억해야 할 또 다른 사항은 this 포인터는 항상 rvalue이며 수정할 수 없다는 것입니다. 그러나 *thisthis 포인터를 역참조합니다.

충분한 배경지식을 거친 후 this*this의 차이점을 이해하기 위해 예제 코드를 살펴보겠습니다.

#include <iostream>
using namespace std;

class Counter {
 private:
  int Count;

 public:
  Counter() { this->Count = 0; }
  void IncreaseCount() { Count++; }
  void PrintCount() { cout << this->Count << endl; }
  Counter* GetCount_Pointer() { return this; }
  Counter GetCount_Copy() { return *this; }
  Counter& GetCount_Reference() { return *this; }
};
int main() {
  // Section-A
  cout << "Sectio-A" << endl;
  Counter C1;
  C1.IncreaseCount();
  Counter* CounterPtr =
      C1.GetCount_Pointer();  // CounterObj will be pointing to C1
  CounterPtr->IncreaseCount();
  C1.PrintCount();

  // Section-B
  cout << "Section-B" << endl;
  Counter C2;
  C2 = C1.GetCount_Copy();
  C1.IncreaseCount();
  C1.PrintCount();
  C2.PrintCount();

  // Section-C
  cout << "Section-B" << endl;
  Counter& CounterRef = C1.GetCount_Reference();
  CounterRef.PrintCount();

  return 0;
}

이 코드 조각은 GetCount 메서드에 대한 여러 메서드가 있는 Counter 클래스를 만듭니다. 첫 번째 메서드(즉, GetCount_Pointer)는 단순히 호출 개체의 주소인 this 포인터의 값을 반환합니다.

GetCount_Copy 메서드는 *this를 반환하는 반면 반환 유형은 Counter 유형 개체입니다. 따라서 이 함수는 호출 개체의 전체 복사본을 반환합니다. 즉, 반환된 복사본을 수정해도 원본 복사본에 영향을 주지 않습니다.

마지막 GetCount_Reference 메서드도 *this를 반환하지만 이 메서드의 반환 유형은 참조 개체(즉, Counter& )입니다. 새로운 전체 복사본을 만드는 대신 컴파일러는 원본 개체에 대한 별칭 또는 참조를 반환합니다.

별칭을 통해 변경한 사항은 원본 개체에도 반영됩니다.

주요 드라이버 코드를 논의하기 전에 프로그램의 출력을 살펴보겠습니다.

출력:

Sectio-A
2
Section-B
3
2
Section-B
3

main 메소드의 섹션 A는 먼저 Counter 유형의 C1 개체를 선언하고 IncreaseCount()를 통해 Count를 증가시킵니다. 나중에 C1.GetCount_Pointer()에 의해 반환된 주소로 CounterPtr 포인터를 초기화합니다.

이제 CounterPtrC1을 가리킬 것입니다. 따라서 CounterPtr을 통해 증분 함수를 호출하면 C1도 수정됩니다.

섹션 B의 C2 = C1.GetCount_Copy()C1.GetCount_Copy()C1의 복사본으로 대체되기 때문에 C1의 모든 현재 내용을 C2에 깊이 복사합니다. 따라서 ‘C1’에 대한 카운트 증가는 ‘C2’에 영향을 미치지 않습니다.

섹션-C는 카운터 유형에 대한 참조 변수를 선언하고 C1.GetCount_Reference()에 의해 반환되는 모든 것으로 초기화합니다. C1.GetCount_Reference()C1의 별칭을 반환하므로 CounterRefC1의 다른 이름이 됩니다.

Counter& CounterRef = C1.GetCount_Reference(); 논리적으로 Counter& CounterRef = C1과 동일합니다.

Muhammad Husnain avatar Muhammad Husnain avatar

Husnain is a professional Software Engineer and a researcher who loves to learn, build, write, and teach. Having worked various jobs in the IT industry, he especially enjoys finding ways to express complex ideas in simple ways through his content. In his free time, Husnain unwinds by thinking about tech fiction to solve problems around him.

LinkedIn

관련 문장 - C++ Pointer