zoukankan      html  css  js  c++  java
  • 【C++】Geekband-专题二:虚指针和内存分配

    1. 传统继承类的设计

    1. static void print_object(const char* name, void* this_, size_t size) {
    2. void** ugly = reinterpret_cast<void**>(this_);
    3. size_t i;
    4. printf("created %s at address %p of size %zu ", name, this_, size);
    5. for(i = 0 ; i < size / sizeof(void*) ; i++) {
    6. printf(" pointer[%zu] == %p ", i, ugly[i]);
    7. }
    8. cout << "-------------------------------"<<endl;
    9. }
    10. class A {
    11. public:
    12. long iA;
    13. long iAA;
    14. A ():iA (1), iAA(10) {print_object(__FUNCTION__, this, sizeof(*this));
    15. }
    16. virtual void f() { cout << "A::f()" << endl; }
    17. virtual void g() { cout << "A::g()" << endl; }
    18. virtual void h() { cout << "A::h()" << endl; }
    19. };
    20. class B : public A {
    21. public:
    22. long iB;
    23. B():iB(2) {
    24. print_object(__FUNCTION__, this, sizeof(*this));
    25. }
    26. virtual void f() { cout << "B::f()" << endl; }
    27. virtual void g_B() { cout << "B::g_B()" << endl; }
    28. virtual void h_B() { cout << "B::h_B()" << endl; }
    29. };
    30. class C : public B{
    31. public:
    32. long iC;
    33. C():iC(3) {
    34. print_object(__FUNCTION__, this, sizeof(*this));
    35. }
    36. virtual void f() { cout << "C::f()" << endl; }
    37. virtual void g_B() { cout << "C::g_B()" << endl; }
    38. virtual void h_C() { cout << "C::h_C()" << endl; }
    39. };
    • A、B、C依次继承
    • 并在构造过程中通过print_object输出构建信息

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

    1. int main()
    2. {
    3. typedef void(*Fun)(void);
    4. long** pVtab = nullptr;
    5. Fun pFun = nullptr;
    6. C c;
    7. pVtab = (long**)&c;
    8. long *cAsLong = (long *)&c;
    9. cout << "C::vptr memory address is " << &cAsLong[0] <<endl;
    10. cout << "[0] C::_vptr->" << endl;
    11. cout << " No. Memory Address Value Function" << endl;
    12. for (int i=0; (Fun)pVtab[0][i] != nullptr; i++){
    13. pFun = (Fun)pVtab[0][i];
    14. cout << " ["<<i<<"] ";
    15. cout << " " << &pVtab[0][i]<<" ";;
    16. cout << " " << (void *)pVtab[0][i]<<" ";;
    17. pFun();
    18. }
    19. cout << " ----------------------------------" << endl;
    20. cout << "[0] addr = " << &pVtab[0] << " ";
    21. cout << "value = " << pVtab[0] << endl;
    22. cout << "[1] addr = "<< &pVtab[1] << " ";
    23. cout << "value = " << pVtab[1] << " ";
    24. cout << "A.iA = " << *((long *) &pVtab[1] )<< endl;
    25. cout << c.iA << endl;
    26. cout << "[2] addr = " << &pVtab[2] << " ";
    27. cout << "value = " << pVtab[2] << " ";
    28. cout << "A.iAA = " << *((long *) &pVtab[2]) << endl;
    29. cout << "[3] addr = " << &pVtab[3] << " ";
    30. cout << "value = " << pVtab[3] << " ";
    31. cout << "B.iB = " << *((long *) &pVtab[3]) << endl;
    32. cout << "[4] addr = " << &pVtab[4] << " ";
    33. cout << "value = " << pVtab[4] << " ";
    34. cout << "C.iC = " << *((long *) &pVtab[4]) << endl;
    35. return 0;
    • pVtab用于显示虚表的位置,并用于后续的直接调用
    • 通过循环,一次输出虚表中各个成员的地址和对应的存储内容
    • 最后,通过直接调用相应的存储内容来调用成员或调用函数。

    3. gdb的使用方法

    • 编译过程
    1. g++ -g -o test.cpp test
    • gdb运行程序
    1. (gdb) r
    • gdb中设置断点
    1. (gdb) break line_number
    • gdb中查询虚表
    1. (gdb) info vtbl c
    • gdb中查询内存内容 - 选择输出的格式
    1. (gdb) x /5xg 0xfffffffd70
    1. (gdb) x /32xg 0x401440

    4. 具体逻辑关系见下图

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

  • 相关阅读:
    多态
    扩展方法
    git 新账户链接新仓库地址
    获取数据类型
    解构赋值
    var let const 无关键字定义变量
    http
    onmouseover、onmouseout、onmouseenter、onmouseleave
    setInterval、setTimeout、requestAnimationFrame
    vue的prop父子组件传值
  • 原文地址:https://www.cnblogs.com/kongww/p/5419954.html
Copyright © 2011-2022 走看看