c++ 内存分布(一)

news/2024/7/3 5:24:39
c++ 内存分布(一)
2011-08-31 10:58
http://hi.baidu.com/kuhntoria/blog/item/d92ec865a54242c48cb10d4e.html

(1)单继承,无虚函数覆盖,无成员变量,无虚继承...1

(2继承无虚函数覆盖 有成员变量,无虚继承...3

(3)单继承有虚函数覆盖 有成员变量无虚继承... 5

(4)单继承 有虚函数覆盖有成员变量 虚继承...6

(5)多重继承 有成员变量虚函数覆盖 无虚继承...10

6)多重继承有成员变量 虚继承...14

(1)单继承,无虚函数覆盖,无成员变量,无虚继承


代码:

#include <iostream>

using namespace std;

class Base//只有三个虚函数

{

public:

virtualvoid f(){cout << "Base::f()" << endl;}

virtualvoid g(){cout << "Base::g()" << endl;}

virtualvoid h(){cout << "Base::h()" << endl;}

};

class Derive: public Base

{

virtualvoid f1(){cout << "Derive::f1()" << endl;}

virtualvoid g1(){cout << "Derive::g1()" << endl;}

virtualvoid h1(){cout << "Derive::h1()" << endl;}

};

typedef void(*fun)(void);

int** pVtbl = NULL;

fun pFun;

int main()

{

Derived;

pVtbl= (int**)(&d);

cout<< "Derive._vptbl->" << endl;

for(int i=0; (fun)pVtbl[0][i] !=NULL; i++)

{

pFun= (fun)pVtbl[0][i];

cout<< " ["<<i<< "]";

pFun();

}

return0;

}

运行结果:




补充:

Sizeof(Base) = 4; sizeof(Derive) = 4; 因为其对象里面都只含有一个虚表指针;无其它成员变量;


(2)继承无虚函数覆盖 有成员变量,无虚继承


#include <iostream>

using namespace std;

class Base

{

public:

char bc;

int bi;

short bs;//这三个是在上面那个程序新加的依次是char int short;

public:

Base():bi(1),bc('b'),bs(1){}

virtualvoid f(){cout << "Base::f()" << endl;}

virtualvoid g(){cout << "Base::g()" << endl;}

virtualvoid h(){cout << "Base::h()" << endl;}

};

class Derive: public Base

{

public:

int di;

char dc;

short ds;//这三个成员变量也是新加的,类型依次是int charshort不同于基类里的声明次序这个要注意,内存对齐就在这里体现出来;

public:

Derive():di(2),dc('d'),ds(2){}

virtualvoid f1(){cout << "Derive::f1()" << endl;}

virtualvoid g1(){cout << "Derive::g1()" << endl;}

virtualvoid h1(){cout << "Derive::h1()" << endl;}

};

Sizeof(Base) = 16;sizeof(Derive) = 24;

下面是Base的成员变量的布局:第一行表示地址假如从0x0000开始存储:

0x0000

0x0001

0x0002

0x0003

0x0004

0x0005

0x0006

0x0007

bc

bi

0x0008

0x0009

bs

这就是自然对齐:内存地址/类型所占字节== 0成员变量bc内存地址为0x0000; char所占字节为10x0000/1 ==0; 满足条件;下一个成员变量bi,不应该放在地址0x0001 0x0002 0x0003的,因为这三个内存地址/4 != 0;所以bi应该放在0x0004;

这样可以得到总共10个字节;

还要考虑内存对齐,所占的字节一定要是其中最大成员所占字节的整数倍;

所以Base所占内存为12字节;

Derive的成员变量的布局,第一行表示地址,假如从0X0000开始存储:

0x0000

0x0001

0x0002

0x0003

0x0004

0x0005

0x0006

0x0007

di

dc

ds

运行结果:



(3)单继承 有虚函数覆盖 有成员变量无虚继承


源代码如上图所示作修改:

运行结果;




我们从表中可以看到下面几点,

1)覆盖的f()函数被放到了虚表中原来父类虚函数的位置。

2)没有被覆盖的函数依旧。

3)父类没有的虚函数在子类对象添加;


http://www.niftyadmin.cn/n/4645239.html

相关文章

c++内存分布(二)--虚函数和虚继承

c内存分布&#xff08;二&#xff09;--虚函数和虚继承http://hi.baidu.com/kuhntoria/blog/item/5872c1fe9bfd5d0d6d22eb22.html2011-08-31 16:20一&#xff0e;多重继承 首先我们先来考虑一个很简单(non-virtual)的多重继承。看看下面这个C类层次结构。 1 class Top 2 { 3 pu…

关于内核符号表

关于内核符号表 http://soft-app.iteye.com/blog/920312 在编写驱动的过程中&#xff0c;常会使用到EXPORT_SYMBOL宏来将定义的函数名导出到内核符号表。以前只是简单的知道如果一个模块中定义的函数要提供给其他模块调用&#xff0c;就必须进行导出。这段时间在编译单个模块…

内核符号表详解

内核符号表详解 http://hi.baidu.com/apollon2010/blog/item/ecbe1d5a3bd2ec8a800a18dc.html 关键词&#xff1a; Kernel Symbol Table、/proc/ksyms、system.map、Oops、LKM 这应该是一个很基本的内核概念&#xff0c;和模块、系统调用等一样基础&#xff0c;但牵涉的东…

如何读取被禁用的网卡信息

http://topic.csdn.net/u/20080310/19/5fa9b49d-c7f5-42be-986f-4cb46fb4e0b0.html?2079547956 比如&#xff0c;有两张网卡&#xff0c;一张启用&#xff0c;一张禁用&#xff0c;如何获取被禁用的网卡的信息&#xff0c;如网卡MAC&#xff0c;网卡名称等。GetAdaptersInfo…

如何在IDA中找到MFC程序的消息处理函数

比起用Win32SDK写的程序&#xff0c;要分析MFC应用程序要麻烦不少。在前者&#xff0c;只要找到注册窗口类的地方就知道其WinProc的位置。那里是程序的控制中心&#xff0c;只要顺藤摸瓜就可以找到你感兴趣的地方。对于用MFC写的程序&#xff0c;这一切都变得复杂起来了。这时&…

距离矢量路由协议通用属性

一、路由分类大多的路由协议都属于两个类别1、距离矢量&#xff08;Distance Ventor&#xff09;、2、链路状态&#xff08;Link State&#xff09;二、距离矢量路由协议因为路由是以矢量&#xff08;距离&#xff0c;方向&#xff09;的方式被通告出去的&#xff0c;其中距离是…

JSR 299 建议草案第二版已提交

昨天 Gavin King 提交了 JSR 299 &#xff08;Contexts and Dependency Injection for the Java EE platform&#xff09;的第二个建议草案 给 JCP。相比上一个建议草案&#xff0c;主要有如下四个大的修订&#xff1a; 在依赖注射注解&#xff08;annotation&#xff09;上全面…

csdn博客集

逆向 http://blog.csdn.net/pll621/article/category/138401 http://blog.csdn.net/cattom/article/category/220275