设为首页 加入收藏

TOP

c++ 对象的内存布局(二)
2015-07-20 17:35:29 来源: 作者: 【 】 浏览:11
Tags:对象 内存 布局
------[3] Child::g_child()
------[4] Child::h_child()
[1] Parent.iparent = 10
[2] Child.ichild = 100
============================================
[0] GrandChild::_vptr->
------[0] GrandChild::f()
------[1] ?Parent::g()
------[2] ?Parent::h()
------[3] GrandChild::g_child()
------[4] Child::h_child()
[1] Parent.iparent = 10
[2] Child.ichild = 100
[3] GrandChild.igrandchild = 1000
============================================
*/
(2)多重继承
下面,再让我们来看看多重继承中的情况,假设有下面这样一个类的继承关系。注意:子类只overwrite了父类的f()函数,而还有一个是自己的函数(我们这样做的目的是为了用g1()作为一个标记来标明子类的虚函数表)。而且每个类中都有一个自己的成员变量:
?
?
?
我们的类继承的源代码如下所示:父类的成员初始为10,20,30,子类的为100
?
使用图片表示是下面这个样子:
?
?
?
我们可以看到:
1) 每个父类都有自己的虚表。
2) 子类的成员函数被放到了第一个父类的表中。
3) 内存布局中,其父类布局依次按声明顺序排列。
4) 每个父类的虚表中的f()函数都被override成了子类的f()。这样做就是为了解决不同的父类类型的指针指向同一个子类实例,而能够调用到实际的函数。
?
代码验证如下
?
?
/*
version: 1.0
author: hellogiser
blog: http://www.cnblogs.com/hellogiser
date: 2014/9/29
*/
?
#include "stdafx.h"
#include
using namespace std;
?
?
class Base1
{
public:
? ? int ibase1;
? ? Base1(): ibase1(10) {}
? ? virtual void f()
? ? {
? ? ? ? cout << "Base1::f()" << endl;
? ? }
? ? virtual void g()
? ? {
? ? ? ? cout << "Base1::g()" << endl;
? ? }
? ? virtual void h()
? ? {
? ? ? ? cout << "Base1::h()" << endl;
? ? }
?
};
?
class Base2
{
public:
? ? int ibase2;
? ? Base2(): ibase2(20) {}
? ? virtual void f()
? ? {
? ? ? ? cout << "Base2::f()" << endl;
? ? }
? ? virtual void g()
? ? {
? ? ? ? cout << "Base2::g()" << endl;
? ? }
? ? virtual void h()
? ? {
? ? ? ? cout << "Base2::h()" << endl;
? ? }
};
?
class Base3
{
public:
? ? int ibase3;
? ? Base3(): ibase3(30) {}
? ? 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
{
public:
? ? int iderive;
? ? Derive(): iderive(100) {}
? ? virtual void f()
? ? {
? ? ? ? cout << "Derive::f()" << endl;
? ? }
? ? virtual void g1()
? ? {
? ? ? ? cout << "Derive::g1()" << endl;
? ? }
};
?
typedef void(*Fun)(void);
?
/*
Base1 vptr---> Derive::f(),Base1::g(),Base1::h(),Derive::g1()
ibase1
Base2 vptr--->Derive::f(),Base2::g(),Base2::h()
ibase2
Base3 vptr--->Derive::f(),Base3::g(),Base3::h()
ibase3
iderive
*/
void test()
{
? ? Derive obj;
? ? Fun pFun;
? ? int **pVtab = (int **)(&obj);
?
? ? int n = 4;
? ? cout << "[0] Base1::_vptr->" << endl;
? ? for (int i = 0; i < n; i++)
? ? {
? ? ? ? pFun = (Fun)pVtab[0][i];
? ? ? ? cout << "------[" << i << "] ";
? ? ? ? pFun();
? ? }
? ? cout << "[1] Base1.ibase1 = " << (int)pVtab[1] << endl;
? ? cout << "============================================" << endl;
? ? n = 3;
? ? cout << "[2] Base2::_vptr->" << endl;
? ? for (int i = 0; i < n; i++)
? ? {
? ? ? ? pFun = (Fun)pVtab[2][i];
? ? ? ? cout << "------[" << i << "] ";
? ? ? ? pFun();
? ? }
? ? cout << "[3] Base2.ibase2 = " << (int)pVtab[3] << endl;
? ? cout << "============================================" << endl;
? ? n = 3;
? ? cout << "[4] Base3::_vptr->" << endl;
? ? for (int i = 0; i < n; i++)
? ? {
? ? ? ? pFun = (Fun)pVtab[4][i];
? ? ? ? cout << "------[" << i << "] ";
? ? ? ? pFun();
? ? }
? ? cout << "[5] Base3.ibase3 = " << (int)pVtab[5] << endl;
? ? cout << "============================================" << endl;
? ? cout << "[6] Derive.iderive = " << (int)pVtab[6] << endl;
}
?
int main()
{
? ? test();
? ? return 0;
}
/*
[0] Base1::_vptr->
------[0] Derive::f()
------[1] Base1::g()
------[2] Base1::h()
------[3] Derive::g1()
[1] Base1.ibase1 = 10
============================================
[2] Base2::_vptr->
------[0] Derive::f()
------[1] Base2::g()
------[2] Base2::h()
[3] Base2.ibase2 = 20
============================================
[4] Base3::_vptr->
------[0] Derive::f()
------[1] Base3::g()
------[2] Base3::h()
[5] Base3.ibase3 = 30
==============
首页 上一页 1 2 3 下一页 尾页 2/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇poj2728 Desert King,最优比例生.. 下一篇C++哪些运算符重载可以重载?

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·在 Redis 中如何查看 (2025-12-26 03:19:03)
·Redis在实际应用中, (2025-12-26 03:19:01)
·Redis配置中`require (2025-12-26 03:18:58)
·Asus Armoury Crate (2025-12-26 02:52:33)
·WindowsFX (LinuxFX) (2025-12-26 02:52:30)