C++ 对象的内存布局

参考陈皓的三篇博客

C++ 虚函数表解析

C++ 对象的内存布局(上)

C++ 对象的内存布局(下)

[C语言面向对象]

虚函数表

实例对象的首地址保存着虚函数表指针

在这里插入图片描述

/*
 * @Description: 测试虚函数指针
 * @Version: 1.0
 * @Autor: hanhy
 */

#include <iostream>

using namespace std;
class Base {
public:
  virtual void f() { cout << "Base::f" << endl; }
  virtual void g() { cout << "Base::g" << endl; }
  virtual void h() { cout << "Base::h" << endl; }
};

int main() {

  cout << "=====================begin test============" << endl;
  Base base;

  cout << "sizeof(base)=" << sizeof(base) << endl; //保存一个虚函数表指针
  cout << "虚函数表地址(虚函数表指针)(16进制):" << (long *)(&base) << endl;
  cout << "虚函数表中第一个函数地址(10进制):" << *(long *)(&base) << endl;
  cout << "虚函数表中第一个函数地址(16进制):" << (long *)*(long *)(&base)
       << endl;

  typedef void (*Fun)(void);

  Fun fun1=(Fun)*((long *)*(long *)(&base)+0);
  fun1();

  Fun fun2=(Fun)*((long *)*(long *)(&base)+1);
  fun2();

  Fun fun3=(Fun)*((long *)*(long *)(&base)+1);
  fun3();
}

在这里插入图片描述

一般继承(无虚函数覆盖)

在这里插入图片描述
在这里插入图片描述

/*
* @Description:一般继承 无覆盖重写虚函数
* @Version: 1.0
* @Autor: hanhy
*/
#include <iostream>

using namespace std;
class Base {
public:
 virtual void f() { cout << "Base::f" << endl; }
 virtual void g() { cout << "Base::g" << endl; }
 virtual void h() { cout << "Base::h" << endl; }
};

class Derive : public Base {};

int main() {

 cout << "=====================begin test============" << endl;
 Derive derive;

 cout << "sizeof(derive)=" << sizeof(derive) << endl; //保存一个虚函数表指针
 cout << "虚函数表地址(虚函数表指针)(16进制):" << (long *)(&derive) << endl;
 cout << "虚函数表中第一个函数地址(10进制):" << *(long *)(&derive) << endl;
 cout << "虚函数表中第一个函数地址(16进制):" << (long *)*(long *)(&derive)
      << endl;

 typedef void (*Fun)();

 Fun fun1=(Fun)*((long *)*(long *)(&derive)+0);
 fun1();

 Fun fun2=(Fun)*((long *)*(long *)(&derive)+1);
 fun2();

 Fun fun3=(Fun)*((long *)*(long *)(&derive)+1);
 fun3();
}

在这里插入图片描述

一般继承(有虚函数覆盖)

在这里插入图片描述
在这里插入图片描述


/*
 * @Description: 一般继承有虚函数覆盖
 * @Version: 1.0
 * @Autor: hanhy
 */

#include <iostream>

using namespace std;
class Base {
public:
  virtual void f() { cout << "Base::f" << endl; }
  virtual void g() { cout << "Base::g" << endl; }
  virtual void h() { cout << "Base::h" << endl; }
};

class Derive : public Base {
  void f() override {cout << "Derive::f" << endl;}

};

int main() {

  cout << "=====================begin test============" << endl;
  Derive derive;

  cout << "sizeof(derive)=" << sizeof(derive) << endl; //保存一个虚函数表指针
  cout << "虚函数表地址(虚函数表指针)(16进制):" << (long *)(&derive) << endl;
  cout << "虚函数表中第一个函数地址(10进制):" << *(long *)(&derive) << endl;
  cout << "虚函数表中第一个函数地址(16进制):" << (long *)*(long *)(&derive)
       << endl;

  typedef void (*Fun)();

  Fun fun1=(Fun)*((long *)*(long *)(&derive)+0);
  fun1();

  Fun fun2=(Fun)*((long *)*(long *)(&derive)+1);
  fun2();

  Fun fun3=(Fun)*((long *)*(long *)(&derive)+1);
  fun3();
}

在这里插入图片描述

多重继承(无虚函数覆盖)

在这里插入图片描述
在这里插入图片描述

/*
 * @Description:多重继承(无虚函数覆盖)
 * @Version: 1.0
 * @Autor: hanhy
 */

#include <iostream>

using namespace std;
class Base1 {
public:
  virtual void f() { cout << "Base1::f" << endl; }
  virtual void g() { cout << "Base1::g" << endl; }
  virtual void h() { cout << "Base1::h" << endl; }
};

class Base2 {
public:
  virtual void f() { cout << "Base2::f" << endl; }
  virtual void g() { cout << "Base2::g" << endl; }
  virtual void h() { cout << "Base2::h" << endl; }
};

class Base3 {
public:
  virtual void f() { cout << "Base3::f" << endl; }
  virtual void g() { cout << "Base3::g" << endl; }
  virtual void h() { cout << "Base3::h" << endl; }
};

class Derive : public Base1, public Base2, public Base3 {};

int main() {

  cout << "=====================begin test============" << endl;
  Derive derive;

  cout << "sizeof(derive)=" << sizeof(derive) << endl; //保存个三虚函数表指针
  cout << "虚函数表地址(虚函数表指针)(16进制):" << (long *)(&derive)
       << endl;
  cout << "虚函数表中第一个函数地址(10进制):" << *(long *)(&derive) << endl;
  cout << "虚函数表中第一个函数地址(16进制):" << (long *)*(long *)(&derive)
       << endl;

  typedef void (*Fun)();

  cout << "------------------第一个虚函数表-------------------" << endl;
  Fun fun1 = (Fun) * ((long *)*(long *)(&derive) + 0);
  fun1();
  Fun fun2 = (Fun) * ((long *)*(long *)(&derive) + 1);
  fun2();
  Fun fun3 = (Fun) * ((long *)*(long *)(&derive) + 2);
  fun3();

  cout << "------------------第二个虚函数表-------------------" << endl;
  Fun fun4 = (Fun) * ((long *)*((long *)(&derive) + 1) + 0);
  fun4();
  Fun fun5 = (Fun) * ((long *)*((long *)(&derive) + 1) + 1);
  fun5();
  Fun fun6 = (Fun) * ((long *)*((long *)(&derive) + 1) + 2);
  fun6();

  cout << "------------------第二个虚函数表-------------------" << endl;
  Fun fun7 = (Fun) * ((long *)*((long *)(&derive) + 2) + 0);
  fun7();
  Fun fun8 = (Fun) * ((long *)*((long *)(&derive) + 2) + 1);
  fun8();
  Fun fun9 = (Fun) * ((long *)*((long *)(&derive) + 2) + 2);
  fun9();
}

在这里插入图片描述

多重继承(有虚函数覆盖)

在这里插入图片描述
在这里插入图片描述

/*
 * @Description:多重继承(有虚函数覆盖)
 * @Version: 1.0
 * @Autor: hanhy
 */

#include <iostream>

using namespace std;
class Base1 {
public:
  virtual void f() { cout << "Base1::f" << endl; }
  virtual void g() { cout << "Base1::g" << endl; }
  virtual void h() { cout << "Base1::h" << endl; }
};

class Base2 {
public:
  virtual void f() { cout << "Base2::f" << endl; }
  virtual void g() { cout << "Base2::g" << endl; }
  virtual void h() { cout << "Base2::h" << endl; }
};

class Base3 {
public:
  virtual void f() { cout << "Base3::f" << endl; }
  virtual void g() { cout << "Base3::g" << endl; }
  virtual void h() { cout << "Base3::h" << endl; }
};

class Derive : public Base1, public Base2, public Base3 {
  void f() override { cout << "Derive::f" << endl; }
};



int main() {

  cout << "=====================begin test============" << endl;
  Derive derive;

  cout << "sizeof(derive)=" << sizeof(derive) << endl; //保存个三虚函数表指针
  cout << "虚函数表地址(虚函数表指针)(16进制):" << (long *)(&derive)
       << endl;
  cout << "虚函数表中第一个函数地址(10进制):" << *(long *)(&derive) << endl;
  cout << "虚函数表中第一个函数地址(16进制):" << (long *)*(long *)(&derive)
       << endl;

  typedef void (*Fun)();

  cout << "------------------第一个虚函数表-------------------" << endl;
  Fun fun1 = (Fun) * ((long *)*(long *)(&derive) + 0);
  fun1();
  Fun fun2 = (Fun) * ((long *)*(long *)(&derive) + 1);
  fun2();
  Fun fun3 = (Fun) * ((long *)*(long *)(&derive) + 2);
  fun3();

  cout << "------------------第二个虚函数表-------------------" << endl;
  Fun fun4 = (Fun) * ((long *)*((long *)(&derive) + 1) + 0);
  fun4();
  Fun fun5 = (Fun) * ((long *)*((long *)(&derive) + 1) + 1);
  fun5();
  Fun fun6 = (Fun) * ((long *)*((long *)(&derive) + 1) + 2);
  fun6();

  cout << "------------------第二个虚函数表-------------------" << endl;
  Fun fun7 = (Fun) * ((long *)*((long *)(&derive) + 2) + 0);
  fun7();
  Fun fun8 = (Fun) * ((long *)*((long *)(&derive) + 2) + 1);
  fun8();
  Fun fun9 = (Fun) * ((long *)*((long *)(&derive) + 2) + 2);
  fun9();
}

在这里插入图片描述

访问非public 虚函数

/*
 * @Description: 访问非public 虚函数
 * @Version: 1.0
 * @Autor: hanhy
 */

#include <iostream>

using namespace std;
class Base {
private:
  virtual void f() { cout << "Base::f" << endl; }
  virtual void g() { cout << "Base::g" << endl; }
  virtual void h() { cout << "Base::h" << endl; }
};

int main(){
  cout << "=====================begin test============" << endl;
  Base base;

  cout << "sizeof(base)=" << sizeof(base) << endl; //保存一个虚函数表指针
  cout << "虚函数表地址(虚函数表指针)(16进制):" << (long *)(&base) << endl;
  cout << "虚函数表中第一个函数地址(10进制):" << *(long *)(&base) << endl;
  cout << "虚函数表中第一个函数地址(16进制):" << (long *)*(long *)(&base)
       << endl;

  typedef void (*Fun)(void);

  Fun fun1=(Fun)*((long *)*(long *)(&base)+0);
  fun1();
  Fun fun2=(Fun)*((long *)*(long *)(&base)+1);
  fun2();
  Fun fun3=(Fun)*((long *)*(long *)(&base)+1);
  fun3();
}

在这里插入图片描述

C++ 对象的内存布局上

在这里插入图片描述

单一的一般继承

在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

海洋2416

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值