TheRiver | blog

You have reached the world's edge, none but devils play past here

0%

成员函数指针

参考

为什么 C++ 中成员函数指针是 16 字节?

demo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
using namespace std;

class _Undefined_class{
public:
void func(void);
};

void* _M_object;
const void* _M_const_object;
void (*_M_function_pointer)();
void (_Undefined_class::*p4)();

int main() {
cout << sizeof(_M_object) << "\n"
<< sizeof(_M_const_object) << "\n"
<< sizeof(_M_function_pointer) << "\n"
<< sizeof(&_Undefined_class::func) << "\n"
<< sizeof(p4) << "\n";
}
8
8
8
16
16

成员函数中是可以使用this指针的,这个以前是知道的,但不够明确的是this指针的存放位置。按目前看的文章,this指针是占用成员函数指针大小的:

A pointer to member function is a pair as follows:

ptr:

For a non-virtual function, this field is a simple function pointer. For a virtual function, it is 1 plus the virtual table offset (in bytes) of the function, represented as a ptrdiff_t. The value zero represents a NULL pointer, independent of the adjustment field value below.

adj:

The required adjustment to this, represented as a ptrdiff_t.

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
31
32
33
34
35
36
37
38
#include <iostream>
#include <cstring>

using namespace std;
struct A {
void foo() const {
std::cout << "A's this:\t" << this << std::endl;
}
char pad0[32];
};

struct B {
void bar() const {
std::cout << "B's this:\t" << this << std::endl;
}
char pad2[64];
};

struct C : A, B
{ };

void call_by_ptr(const C &obj, void (C::*mem_func)() const)
{
void *data[2];
std::memcpy(data, &mem_func, sizeof(mem_func));
std::cout << "------------------------------\n"
"Object ptr:\t" << &obj <<
"\nFunction ptr:\t" << data[0] <<
"\nPointer adj:\t" << data[1] << std::endl;
(obj.*mem_func)();
}

int main()
{
C obj;
call_by_ptr(obj, &C::foo);
call_by_ptr(obj, &C::bar);
}
------------------------------
Object ptr:     0x7ffd3b46ec80
Function ptr:   0x400a56
Pointer adj:    0
A's this:       0x7ffd3b46ec80
------------------------------
Object ptr:     0x7ffd3b46ec80
Function ptr:   0x400a90
Pointer adj:    0x20
B's this:       0x7ffd3b46eca0

ending

----------- ending -----------