C++类内存结构布局

 

分类:C
2011-01-16 09:40 阅读(379)评论(0)编辑删除
一、没有虚函数,没有继承的类内存结构:
1.如下定义一个类:
class A
{
public:
void seta(int x) {a = x;};
void setb(int x) {b = x;};
int  sum() {return a+b;};
private:
int a;
int b;
};
A test;
当实例化以后,实际上实例test的内存结构只有两个变量成员a和b;
而类的函数在操作时,其输入参数比实际看到的多一个,即寄存器ecx,ecx指向实例地址。比如在例子中,函数seta的代码是如下的:

       mov     eax, [esp+arg_0]
       mov     [ecx], eax
       retn    4
也就是说,A.seta的实际上可以这样写: void seta(&A,int x);
2.在类中,变量是按定义的顺序组织的。不管这些变量是public,privated还是protected。
二、没有虚函数,有继承的类内存结构:
class A
public:
void seta(int x){a = x;};
privated:
int a;
};
class B:class A
{
public:
void setb(int x){b = x;};
privated:
int b;
};
在这样的实例中,先分配父类变量,再分配子类变量。
如果是多重继承的话,则按顺序分配父类的变量。
三、有虚函数,没有继承的类内存结构:
若果类中含有虚函数时,类对象的内存分配有不一样的地方。如:
class A
{
public:
virtual init(int x,int y){a = x;b = y;};
virtual init(){a = 0;b=0;};
int sum();
priviate:
int a,b;
}
此时,在类实例内存中,首先是虚函数表指针,然后才分配变量。
vc6编译器下,当虚函数个数为偶数时,已0xffffffff结束。为奇数时,先填充0,再已0xffffffff结束。
四、有虚函数,单继承的类内存结构:
单继承关系分为虚函数覆盖和不覆盖两种,当不覆盖时,虚函数表先是父类的虚函数表,然后是子类的虚函数表,当覆盖时,同样排序,但父类的被覆盖虚函数地址为子类的相应的虚函数的地址。
变量的分配和上面的相同。
五、有虚函数,多继承的类内存结构:
class C
{
public:
  virtual C1(){return 1;};
  virtual C2(){return 2;};
  setc(int x){c = x;};
private:
  int c;
};
class B
{
public:
  virtual B1(){d1=1;};
  virtual B2(){d2=2;};
private:
  int d1;
  int d2;
};
 
class A
{
public: 
  int sum(){return a1+a2;};
  virtual  A1(int x,int y){a1 = x;a2 = y;};
  virtual  A2(){a3=0;};
  virtual  A3(int x){a3 = x;};
  virtual  A4(){a1*a2*a3;};
private:
  int a1;
  int a2;
  int a3;
};
class D:public A,public B,public C
{
public:
  virtual D1(int x,int y){d1=x+10;d2=y+10;d3=d1*5;d4=d2*7;};
  virtual D2(){return 8;};
private:
  int d1,d2,d3,d4; 
};
此时,类D 的实例的内存分配应该如下:
A的虚函数表指针,紧跟这个虚函数表的是D的虚函数地址。
A的变量分配
B的虚函数表指针
B的变量分配
C的虚函数表指针
C的变量分配
D的变量分配
如果有虚函数覆盖,则和上面描述相同,用D的虚函数地址覆盖相应的父类的虚函数表中虚函数的地址。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/353663.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用Boxfuse为您的REST API设置https

在我的上 一篇 文章中,我展示了在Boxfuse的帮助下,基于Spring Boot框架建立REST API并在AWS上运行非常容易 。 下一步是利用SSL与API进行通信。 通过使用SSL,我们确保在REST API服务器和API客户端之间的传输过程中保存了数据 。 要为Spring B…

Python类与对象实验

一、任务描述 本实验任务主要对Python类与对象进行一些基本操作,通过完成本实验任务,要求学生熟练掌握Python类与对象的关系,并对Python类与对象的基本操作进行整理并填写工作任务报告。 二、任务目标 1、掌握Python类的创建 2、掌握类对象 三…

c++类的内存布局

by andydeng • 2011 年 4 月 3 日 • C • 1 Comment 本文基本上是对于Stanley B.Lippman的Inside The C Object Model一书第一章第三章的概括,描述了c类的内存布局情况. c的类的内存布局有如下规则: 1. Nonstatic data member 存放在Class Object中; 2. Static data membe…

matlab 五点三次平滑算法

(2012-04-23 21:01:31) 转载▼标签: 杂谈 分类: matlab http://www.ilovematlab.cn/thread-71818-1-1.html 这里提供一个函数mean5_3(五点三次平滑算法)对数据进行平滑处理: load V1.mat subplot 211; plot(V1); ylim([2000 7000]); grid; y…

spring配置xml文件_XML配置文件中的Spring配置文件

spring配置xml文件我的上一个博客非常简单,因为它涵盖了我从Spring 3.0.x到Spring 3.1.x的轻松升级,最后我提到可以将Spring模式升级到3.1,以利用Spring的最新功能。 在今天的博客中,我将介绍这些功能中最酷的功能之一&#xff1a…

数组指针和指针数组的区别

数组指针(也称行指针) 定义 int (*p)[n]; ()优先级高,首先说明p是一个指针,指向一个整型的一维数组,这个一维数组的长度是n,也可以说是p的步长。也就是说执行p1时,p要跨过n个整型数据的长度。 如…

用JS写的取存款功能

console.log("请输入用户名:");let username readline.question(); // 接收用户输入的用户名console.log("请输入密码:");let password readline.question(); // 接收用户输入的密码let arr [["123", "123…

您在2016年OpenStack峰会上错过的事情

今年我第一次参加了4月25日至29日在德克萨斯州奥斯汀举行的OpenStack峰会。 今天结束了,我要回家了,我想回顾一下,从我的角度分享你错过的事情。 作为以应用程序开发人员为重点的技术传播者,转移到包含Red Hat产品组合的基础架构…

HDU1069 最长上升子序列

emm。。。。矩形嵌套 还记得吗。。。。就是它。。。 直接贴代码了。。。。 import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.Scanner;public class Main{final static int maxn 1000000;…

linux 中配置假域名来测试

1.linux中配置假域名 找到hosts文件进行编辑 命令:vim /etc/hosts 配置: #centos(本机IP)192.168.1.179 www.imooc.com(假域名,自己设置)192.168.1.179 image.imooc.com192.168.1.179 s.imooc.c…

C/C++中的常量指针与指针常量

常量指针 常量指针是指向常量的指针,指针指向的内存地址的内容是不可修改的。 常量指针定义“const int *p&a;”告诉编译器,*p是常量,不能将*p作为左值进行操作。但这里的指针p还是一个变量,它的内容存放常量的地址&#xff0…

基于javafx的五子棋_JavaFX中基于表达式的PathTransitions

基于javafx的五子棋在JavaFX中,您可以使用PathTransition对象为路径上的节点设置动画。 PathTransitions使用Shape对象来描述它们需要沿其动画的路径。 JavaFX提供了各种类型的形状(例如,多边形,圆形,多边形&#xff0…

ES6三种暴露方法

1.多行暴露(分行暴露) 导出 //test.js export function test1(){console.log(测试分别导出test1); } export function test2(){console.log(测试分别导出test2); } 导入: //index.js import {test1, test2} from ./test.js //文件路径二&…

shell获取当前执行脚本的路径

filepath$(cd "$(dirname "$0")"; pwd)脚本文件的绝对路径存在了环境变量filepath中,可以用echo $filepath查看完整路径在shell中:$0: 获取当前脚本的名称$#: 传递给脚本的参数个数$$: shell脚本的进程号$1, $2, $3...:脚…

MANIFEST.MF文件详解

参考百度百科的解释如下: http://baike.baidu.com/item/MANIFEST.MF MANIFEST.MF:这个 manifest 文件定义了与扩展和包相关的数据。单词“manifest”的意思是“显示” ### MANIFEST.MF文件介绍------------------------------ 主要包含3个部分 - Manifes…

Drools 6.4.0.Final提供

最新和最出色的Drools 6.4.0.Final版本现已可供下载。 这是我们先前构建的增量版本,对核心引擎和Web工作台进行了一些改进。 您可以在此处找到更多详细信息,下载和文档: Drools网站 资料下载 文献资料 发行说明 请阅读下面的一些发行要…

Linux Shell中各种分号和括号的用法总结

[日期:2011-02-21] 来源:Linux社区 作者:破烂熊 [字体:大 中 小] 各种括号的用法总结如下 1.Shell中变量的原形:${var} 大家常见的变量形式都是$var 2.命令替换$(cmd) 命令替换$(cmd)和符号cmd(注意这不是单引号…

软考解析:2014年下半年下午试题

软考解析:2014年下半年下午试题 第一题:数据流图 第四题:算法题 第五题:Java设计模式 转载于:https://www.cnblogs.com/MrSaver/p/9073778.html

malloc()参数为0的情况

问题来自于《程序员面试宝典(第三版)》第12.2节问题9(这里不评价《程序员面试宝典》,就题论题): 下面的代码片段输出是什么?为什么? char *ptr;if((ptr (char *)malloc(0))NULL)put…

铁乐学python_Day42_锁和队列

铁乐学python_Day42_锁和队列 例:多个线程抢占资源的情况 from threading import Thread import timedef work():global ntemp ntime.sleep(0.1)n temp - 1if __name__ __main__:n 100l []for i in range(100):p Thread(targetwork)l.append(p)p.start()for p…