原创文章
C++ 类外调用类内的私有函数
(完全没什么用瞎折腾系列)
代码
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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <iostream>
#include <stdint.h>
#if UINTPTR_MAX == 0xffffffff
/* 32-bit */
typedef uint32_t POINTER_BASE;
#elif UINTPTR_MAX == 0xffffffffffffffff
/* 64-bit */
typedef uint64_t POINTER_BASE;
#else
/* wtf */
typedef NULL POINTER_BASE;
#endif
using namespace std;
class A {
private:
virtual void f(void) {
cout << "Hello A::f()" << endl;
}
void g(void) {
cout << "Hello A::g()" << endl;
}
static void j(void) {
cout << "Hello A::j()" << endl;
}
virtual void i(void) {
cout << "Hello A::i()" << endl;
}
A() {
void(A::*pAF)(void) = &A::g;
pf_a = (POINTER_BASE*)(*(POINTER_BASE*)(&pAF));
void(*pSAF)(void) = &A::j;
psf_a = (POINTER_BASE*)pSAF;
}
virtual ~A() {
if (nullptr != obj) delete obj;
}
static A* obj;
public:
static A* getInstance() {
if (nullptr == obj) obj = new A();
return obj;
}
POINTER_BASE *pf_a;
POINTER_BASE *psf_a;
};
A* A::obj = nullptr;
int main() {
A *a = A::getInstance();
POINTER_BASE b = *((POINTER_BASE*)&(*a));
typedef void(*P_FUN)(void);
P_FUN pF;
pF = (P_FUN)(*((POINTER_BASE*)(*(POINTER_BASE*)(&b)) + 1));
pF(); // call private virtual void A::i(void)
pF = (P_FUN)(a->pf_a);
pF(); // call private void A::g(void)
pF = (P_FUN)(a->psf_a);
pF(); // call private static void A::j(void)
return 0;
}
输出
1
2
3
Hello A::i()
Hello A::g()
Hello A::j()
解析
-
调用
A::i()
就是虚函数表查表,用vs debug一下就能看到一个叫__vfptr
的变量(virtual function pointer),如图 -
调用
A::g()
和A::j()
差别不大,都是想办法把函数指针整出去,唯一的区别就是j
函数加了static之后貌似没有命名空间的限制了