'this'포인터는 컴퓨터 메모리에 어디에 저장합니까?
'this'포인터는 정확히 어디에 메모리에 저장? 스택, 힙 또는 데이터 세그먼트에 할당?
#include <iostream>
using namespace std;
class ClassA
{
int a, b;
public:
void add()
{
a = 10;
b = 20;
cout << a << b << endl;
}
};
int main()
{
ClassA obj;
obj.add();
return 0;
}
위의 코드에서 멤버 함수를 호출하고 add()
당사자 개체는 'this'포인터로 암시 적으로 전달됩니다. this
에는 메모리 어디에 저장됩니까?
다른 답변은 일반적인 컴파일러가 구현하는 방법을 설명하는 매우 좋은 작업을 수행했습니다 this
(함수에 암시 적 첫 번째 매개 변수로 전달하여).
C ++ ISO 사양이 이것에 대해 명시 적으로 말하는 것을 보는 것도 유용하다고 생각합니다. C ++ 03 ISO 사양, §9.3.2 / 1에 따르면 :
비 정적 (9.3) 멤버 함수의 본문에서 키워드
this
는 값이 함수가 호출되는 객체 주소 인 비 lvalue 어디에입니다.
그것은 그 노트에 중요 this
하다 하지 변수-그것은 표현 많이 표현하는 것과 같은 방식으로 1 + 2 * 3
표현입니다. 이 경우에는 거의 모든 곳에 저장할 수 있습니다. 컴파일러 수도 스택에 선언 할 함수에 내재라고 전달할 함수에, 그 수 있습니다. C ++ 사양은 의도적으로 구현에 약간의 유연성을 제공합니다.
"언어 변호사"의 대답은 "이것은 완전히 구현에 정의되어 있고 this
기술적으로 포인터가 아니라 포인터로 평가되는"이라고 생각합니다.
도움이 되셨기를 바랍니다!
가장 쉬운 방법 this
은 항상 자동으로 전달되는 숨겨진 인수로 생각하는 것입니다 .
따라서 다음과 같은 가상의 방법이 있습니다.
size_t String::length(void) const
{
return strlen(m_string);
}
실제로는 다음과 가능합니다.
size_t String__length(const String *this)
{
return strlen(this->m_string);
}
다음과 같은 전화 :
{
String example("hello");
cout << example.length();
}
다음과 같이됩니다.
cout << String__length(&example);
위의 변환이 단순화되어 내 요점이 더 명확하게 해지기를 바랍니다. "와우 없습니다, 메소드 오버로딩에 대한 마샬링은 어디입니까?"라는 유형의 이의로 주석을 채울 필요가 있습니다. :)
그것은 질문을 "인수가 저장되는 위치"로 바꾸고, 대답은 당연히 "따라"입니다. :)
스택에있는 경우가 많지만 많은 경우에도 사용할 수 있거나 대상 아키텍처에 적합하거나 다른 스택이있을 수 있습니다.
this
일반적으로 메서드의 숨겨진 인수로 전달됩니다 (다른 호출 규칙에서 유일한 차이점은 방법입니다 ).
전화하는 경우 :
myClass.Method(1, 2, 3);
컴파일러는 다음 코드를 생성합니다.
Method(&myClass, 1, 2, 3);
첫 번째 매개 변수는 실제로에 대한 포인터 this
입니다.
다음 코드를 확인해 보겠습니다.
class MyClass
{
private:
int a;
public:
void __stdcall Method(int i)
{
a = i;
}
};
int main(int argc, char *argv[])
{
MyClass myClass;
myClass.Method(5);
return 0;
}
사용 가능한 __stdcall
컴파일러가 모든 매개 변수를 스택을 통해 전달했습니다. 그런 다음 디버거를 시작하고 어셈블리 코드를 검사하면 다음과 같은 것을 사용할 수 있습니다.
myClass.Method(5);
00AA31BE push 5
00AA31C0 lea eax,[myClass]
00AA31C3 push eax
00AA31C4 call MyClass::Method (0AA1447h)
보시다시피, 메소드의 매개 변수가 스택을 통해 전달 된 다음 myClass의 주소가 eax 레지스터에로드되고 다시 스택에 푸시됩니다. 즉, this
이 메소드의 일반 매개 변수로 처리됩니다.
this
rvalue (주소를 사용할 수 없음)이므로 메모리를 전혀 차지하지 않습니다. 컴파일러 및 대상 아키텍처에 따라 종종 레지스터에 있습니다. Sparc의 i0, Intel의 MSVC가있는 ECX 등. 최적화 프로그램이 활성화되면 이동할 수도 있습니다. (MSVC의 다른 레지스터에서 본 적이 있습니다).
this
대부분 함수 인수처럼 동작하므로 스택에 저장되거나 아키텍처의 이진 호출 규칙이 허용하는 경우 레지스터에 저장됩니다.
this
잘 정의 된 위치에 저장되지 않습니다! 가리키는 객체는 어딘가에 저장되고 잘 정의 된 주소를 가지고 있지만 주소 자체에는 특정 집 주소가 없습니다. 프로그램 내에서 소통됩니다. 뿐만 아니라 그 포인터의 사본이 많이있을 수 있습니다.
다음 가상 init
함수에서 객체는 가상 이벤트 소스 객체를 사용하여 이벤트 및 타이머 콜백을 수신하기 위해 자신을 등록합니다. 따라서 등록 후 두 개의 추가 사본이 있습니다 this
.
void foo_listener::init()
{
g_usb_events.register(this); // register to receive USB events
g_timer.register(this, 5); // register for a 5 second timer
}
나는 함수 활성화 체인이며 this 포인터의 여러 복사본이 있습니다. 객체가 obj
있고 그 foo
함수를 호출 한다고 가정 합니다. 이 함수는 동일한 객체의 bar
함수를 bar
호출 하고 라는 다른 함수를 호출 update
합니다. 각 기능 활성화 수준에는 this
포인터가 있습니다. 기계 레지스터 또는 기능 활성화 스택 프레임의 메모리 위치에 저장됩니다.
참고 URL : https://stackoverflow.com/questions/16585562/where-is-the-this-pointer-stored-in-computer-memory
'ProgramingTip' 카테고리의 다른 글
프로그래밍 방식으로 PopupMenu 메뉴 항목 설정 (0) | 2020.11.22 |
---|---|
오류 : 기호 변수 abc_ic_ab_back_mtrl_am_alpha를 사용할 수 없습니다. (0) | 2020.11.22 |
소수점 앞의 자릿수 가져 오기 (0) | 2020.11.22 |
함수가 함수에 대한 포인터를 반환하는 방법은 무엇입니까? (0) | 2020.11.22 |
DataContractSerializer를 사용하여 생성 화하지만 역화 할 수 없음 (0) | 2020.11.22 |