a와 b클래스를 다중상속하는 c클래스가 있다고 하자.
코드
여기서는 28 이랑 2C 인데 C는 12이므로 딱 4만큼의 차이가 있다.
class A
{
public:
int a;
//void fa()
//{ cout << this << endl; }
};
class B
{
int b;
//void fb()
//{
// cout << this << endl;
//}
};
class C : public A, public B
{
int c;
};
int main()
{
C obj;
A* pA = &obj;
B* pB = &obj;
std::dec;
cout << &obj << endl;
cout << pA << endl;
cout << pB << endl;
}
-> obj 객체를 통해서 기반클래스의 함수들을 호출했는데 this 포인터가 다르다는 것을 확인할 수 있다.
class Base1 {
public:
int a;
void f1() {
cout << this << endl;
};
};
class Base2 {
public:
int b;
void f2() {
cout << this << endl;
};
};
class Derived : public Base1, public Base2 {
public:
int c;
void f3() {
cout << this << endl;
};
};
void main() {
Derived obj;
//아래 결과도 위의 샘플 코드와 동일한 형태로 출력된다.
obj.f3(); // obj의 주소
obj.f1(); // obj의 주소
obj.f2(); // obj + sizeof(Base1) 주소
void(Derived:: * fp)(); //Derived 클래스의 멤버 함수 포인터 선언
//아래 결과도 위와 동일한 형태로 출력된다.
fp = &Derived::f3;
(obj.*fp)();
fp = &Derived::f1;
(obj.*fp)();
fp = &Derived::f2;
(obj.*fp)();
}
멤버 함수 포인터는 일반 함수 포인터와 다르게 함수의 주소를 저장하는 부분과 this 객체의 offset을 저장하는 부분으로 구분되어 있다. 그래서 멤버 함수 포인터 변수에 멤버 함수의 주소를 지정할 때 해당 함수가 어느 클래스에 속해 있는지에 따라 offset 크기도 같이 저장하게 된다.
따라서, Derived::f1 과 Derived::f3의 주소를 저장할 때는 offset값이 0으로, Derived::f2의 주소를 저장할 때는 sizeof(Base1)한 값이 offset으로 저장되어 멤버 함수 포인터 변수를 통해 함수를 호출할 때 this 값의 위치가 변경되어 들어가게 된다.
1번과 2번 예제에서 얻은 결과와 동일한 내용임.
problem
: 멤버 함수 포인터를 이용해 클래스 Point의 멤버 데이터인 x,y를 참조한 후,
주소값을 출력하라.
int Point::*p2 = &Point::x;
int Point::*p3 = &Point::y;
cout << p2 << endl;
cout << p3 << endl;