您的位置:首页 > 编程语言 > C语言/C++

【C++】Geekband-专题二:虚指针和内存分配

2016-04-22 09:13 351 查看

1. 传统继承类的设计

static void print_object(const char* name, void* this_, size_t size) {

void** ugly = reinterpret_cast<void**>(this_);

size_t i;

printf("created %s at address %p of size %zu\n", name, this_, size);

for(i = 0 ; i < size / sizeof(void*) ; i++) {

printf("  pointer[%zu] == %p\n", i, ugly[i]);

}

cout << "-------------------------------"<<endl;

}

class A {

public:

long iA;

long iAA;

A ():iA (1), iAA(10) {print_object(__FUNCTION__, this, sizeof(*this));

}

virtual void f() { cout << "A::f()" << endl; }

virtual void g() { cout << "A::g()" << endl; }

virtual void h() { cout << "A::h()" << endl; }


};


class B : public A {

public:

long iB;

B():iB(2) {

print_object(__FUNCTION__, this, sizeof(*this));


}

virtual void f() { cout << "B::f()" << endl; }

virtual void g_B() { cout << "B::g_B()" << endl; }

virtual void h_B() { cout << "B::h_B()" << endl; }

};

class C : public B{

public:

long iC;

C():iC(3) {

print_object(__FUNCTION__, this, sizeof(*this));

}

virtual void f() { cout << "C::f()" << endl; }

virtual void g_B() { cout << "C::g_B()" << endl; }

virtual void h_C() { cout << "C::h_C()" << endl; }

};

[/code]

A、B、C依次继承

并在构造过程中通过
print_object
输出构建信息

2. 构造
Class C
,并通过指针来一次访问内容或调用函数

int main()

{

typedef void(*Fun)(void);

long** pVtab = nullptr;

Fun pFun = nullptr;

C c;

pVtab = (long**)&c;

long *cAsLong = (long *)&c;

cout << "C::vptr memory address is " << &cAsLong[0] <<endl;

cout << "[0] C::_vptr->" << endl;

cout << "    No.\tMemory Address\t Value\t\tFunction" << endl;

for (int i=0; (Fun)pVtab[0][i] != nullptr; i++){

pFun = (Fun)pVtab[0][i];

cout << "    ["<<i<<"]\t";

cout << " " << &pVtab[0][i]<<"\t";;

cout << " " << (void *)pVtab[0][i]<<"\t";;

pFun();

}

cout << " ----------------------------------" << endl;

cout << "[0] addr = " << &pVtab[0] << "\t";

cout << "value = " << pVtab[0] << endl;

cout << "[1] addr = "<< &pVtab[1] << "\t";

cout << "value = " << pVtab[1] << "\t";

cout << "A.iA = " << *((long *) &pVtab[1] )<< endl;

cout << c.iA << endl;

cout << "[2] addr = " << &pVtab[2] << "\t";

cout << "value = " << pVtab[2] << "\t";

cout << "A.iAA = " << *((long *) &pVtab[2]) << endl;

cout << "[3] addr = " << &pVtab[3] << "\t";

cout << "value = " << pVtab[3] << "\t";

cout << "B.iB = " << *((long *) &pVtab[3]) << endl;

cout << "[4] addr = " << &pVtab[4] << "\t";

cout << "value = " << pVtab[4] << "\t";

cout << "C.iC = " << *((long *) &pVtab[4]) << endl;

return 0;

[/code]

pVtab
用于显示虚表的位置,并用于后续的直接调用

通过循环,一次输出虚表中各个成员的地址和对应的存储内容

最后,通过直接调用相应的存储内容来调用成员或调用函数。

3. gdb的使用方法

编译过程

g++ -g -o test.cpp test

[/code]

gdb运行程序

(gdb) r

[/code]

gdb中设置断点

(gdb) break line_number

[/code]

gdb中查询虚表

(gdb) info vtbl c

[/code]

gdb中查询内存内容 - 选择输出的格式

(gdb) x /5xg 0xfffffffd70

[/code]

(gdb) x /32xg 0x401440

[/code]

4. 具体逻辑关系见下图

http://7xlos6.com1.z0.glb.clouddn.com/%E6%9D%82.png

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: