일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 |
- c++ basic practice
- discord bot
- placement new
- vector size
- increment operator
- delete function
- std::ostream
- std::cout
- vector capacity
- c++ multi chatting room
- new&delete
- C++
- virtual function table
- dynamic_cast
- operator overloading
- base from member
- pointer to member data
- virtual function
- return by reference
- std::vector
- virtual inheritance
- virtual destructor
- suffix return type
- constructor
- conversion constructor
- member function pointer
- diamond inheritance
- std::endl
- this call
- 더 지니어스 양면포커
- Today
- Total
I'm FanJae.
[C++ Intermediate] this call 본문
1. this call
1-1. 멤버 함수의 의문점.
class Point
{
int x{0};
int y{0};
public:
void set(int a, int b)
{
x = a;
y = b;
}
};
int main()
{
Point pt1;
Point pt2;
pt1.set(10, 20);
pt2.set(10, 20);
}
- 멤버 데이터는 객체당 한 개씩 생성된다.
- 멤버 함수는 코드 메모리에 한 개만 만들어져 있다.
- 객체가 여러 개 생성되어도 멤버 함수는 한 개만 있다.
※ 함수 인자는 2개 (a, b) 밖에 없는데, x가 어떤 객체의 멤버 인지(pt1.x인지 pt2.x 인지) 어떻게 아는가?
1-2. 어떤 변환이 일어나는가?
class Point
{
int x{0};
int y{0};
public:
void set(Point*this, int a, int b)
{
this->x = a;
this->y = b;
}
};
int main()
{
Point pt1;
Point pt2;
pt1.set(10, 20); // set(&p1, 10, 20);
pt2.set(10, 20);
}
- 약간의 차이가 있지만 C++ 컴파일러에 의해서 이러한 형태로 변환된다.
- 멤버 함수 호출 시 객체의 정보(주소)가 같이 전달되는 것을 this call이라고 한다.
※ 실제 함수 인자가 전달되는 방식과 객체 주소가 전달되는 방식은 약간의 차이가 있다.
(32bit/64bit 환경, 컴파일러에 따라서도 차이가 존재한다.)
1-3. static 멤버 함수
class Point
{
int x{0};
int y{0};
public:
void set(int a, int b)
{
x = a;
y = b;
}
static void foo(int a)
{
x = a; // this->x = a로 변경할 수 없다.
// error
}
};
int main()
{
Point pt1;
Point pt2;
pt1.set(10, 20); // Point::set(&pt1, 10, 20)
pt2.set(10, 20); // Point::set(&pt2, 10, 20)
Point::foo(10); // Point::foo(10)
pt1.foo(10); // Point::foo(10)
}
- static 멤버 함수는 객체의 주소가 전달되지 않는다. 즉, this call이 아니다.
- 객체의 주소를 알 수 없기 때문에 x,y에 접근할 수 없다.
1-4. 정리
① non-static 멤버 함수 호출 시
- 객체의 정보(주소)가 같이 전달된다.
- this call
② static 멤버 함수 호출 시
- 객체의 정보(주소)가 같이 전달되지 않는다.
- this call이 아니다.
※ Aseembly Level에서 확인하면 인자로 보낸 값 이외에 추가로 한 값을 더 넣는 것을 볼 수 있다.
2. 상수 멤버 함수와 this
class Object
{
public:
void foo() {}
void goo() const {}
};
int main()
{
Object obj;
obj.foo(); // ok
obj.goo(); // ok
const Object cobj;
cobj.foo(); // error
cobj.goo(); // ok
}
- 일반적으로 상수 객체는 상수 멤버 함수만 호출이 가능하다.
- 따라서 cobj는 foo()를 호출할 수 없다.
class Object
{
public:
void foo(Object* this) {}
void goo(const Object* this) {}
};
int main()
{
Object obj;
obj.foo(); // ok
obj.goo(); // ok
const Object cobj;
cobj.foo(); // Object* this = &cobj;
cobj.goo(); // const Object* this = &cobj;
}
- 즉, 컴파일러가 변경한 코드가 이와 같이 변경되는 것이다.
- 상수의 주소를 상수가 아닌 것을 가리키는 포인터에 담을 수 없다.
'C++ > Intermediate' 카테고리의 다른 글
[C++ Intermediate] Member Function Pointer (2) | 2024.09.23 |
---|---|
[C++ Intermediate] Trivial (4) | 2024.09.19 |
[C++ Intermediate] new/delete, placement new (0) | 2024.09.18 |
[C++ Intermediate] 객체의 변환(Conversion) (0) | 2024.09.13 |
[C++ Intermediate] Constructor 생성 원리 (1) | 2024.09.10 |