深入分析C++中类的大小

首先看一个例子:


复制代码 代码如下:

#include <iostream>
 using namespace std;

class A{};

class B
 {
     int b;
     char c;
 };

class C
 {
     int c1;   
     static int c2;
 };
 int C::c2 = 1;

class D:public C,public B{
     int d;
 };
 int main()
 {
     cout<<"sizeof(A)="<<sizeof(A)<<endl;
     cout<<"sizeof(B)="<<sizeof(B)<<endl;
     cout<<"sizeof(C)="<<sizeof(C)<<endl;
     cout<<"sizeof(D)="<<sizeof(D)<<endl;

return 0;
 }

运行结果为:

sizeof(A)=1

sizeof(B)=8

sizeof(C)=4

sizeof(D)=16

对于类A来说,虽然A是一个空类,但为了便于空类进行实例化,编译器往往会给它分配一个字节,这样A实例化后便在内存中有了一个独一无二的地址.对于类B,B的大小应为sizeof(int)+sizeof(char)=5,但是考虑内存对齐,B的大小应为8.对于类C,类的静态成员变量被放在全局区,和类的普通成员并没有放在一块。类的静态成员被声明后就已存在,而非静态成员只有类被实例化后才存在。所以C的大小为sizeof(int)=4。D的大小为B+C的大小+自身数据成员的大小,一共为16.

==========================分割线在这里====================================

下面讨论含有虚函数的类的大小:


复制代码 代码如下:

#include <iostream>
 using namespace std;

class A
 {
 public:
     void virtual aa(){};
 };

class B:public A
 {
     void virtual bb(){};
 };

class C:virtual A
 {
 public:
     void virtual aa(){};
     void cc(){};
 };

class D:virtual A
 {
 public:
     void virtual dd(){};
 };

int main()
 {
     cout<<"sizeof(A)="<<sizeof(A)<<endl;
     cout<<"sizeof(B)="<<sizeof(B)<<endl;
     cout<<"sizeof(C)="<<sizeof(C)<<endl;
     cout<<"sizeof(D)="<<sizeof(D)<<endl;

return 0;
 }

运行结果为:

sizeof(A)=4

sizeof(B)=4

sizeof(C)=8

sizeof(D)=12

对于class A,它含有一个虚函数,编译器会为虚函数生成一张虚函数表,来记录对应的函数地址,为此,在class A的内存地址中要有一个vfptr_A指针指向这个虚表,所以class A的大小为指针大小,即4.(注意,无论类中有多少个虚函数,它们的大小都是4,因为内存中只需要保存这个指针即可)。

对于class B,它是public继承A,虽然它也有一个虚函数,但是从结果看,B应该和A都在B的vtable(虚表中),所以class B的大小为4.

对于class C,它是vitual 继承A,所以要有一个指向父类A的指针,占有4字节大小aa()是继承自class A的虚函数,从结果来看,它没有在内存中占有空间,所以C的大小为sizeof(A)+4=8.

对于class D,它是虚继承class A,同上,要有一个指向父类A的指针,同时,class D中有虚函数,所以要有一个指向虚表的指针,所以sizeof(D)=sizeof(A)+4+4=12

时间: 2013-05-02

c++动态内存空间示例(自定义空间类型大小和空间长度)

动态内存空间的申请示范 利用C++的特性,能够自定义空间的类型大小和空间长度 下面这个程序是个数组动态配置的简单示例 复制代码 代码如下: #include <iostream>using namespace std; int main(){   int size = 0; cout << "请输入数组长度:";  //能够自定义的动态申请空间长度    cin >> size;    int *arr_Point = new int[size];

C++空类详解

空类默认产生的成员:class Empty {};Empty(); // 默认构造函数Empty( const Empty& ); // 默认拷贝构造函数~Empty(); // 默认析构函数Empty& operator=( const Empty& );  // 默认赋值运算符Empty* operator&();               // 取址运算符const Empty* operator&() const;    // 取址运算符 const 给出

C++空类及没有成员变量的类的大小实例分析

众所周知的C++中空类的大小为1,但是除了空类之外的其他一些没有成员变量的类的大小,还是有相当一部分开发人员对此有很多不明之处的. 这里我们以如下代码为例: #include using namespace std; class a {}; class b{}; class c :public a{ virtual void fun() = 0; }; class d :public b, public c{}; int main() { cout << "sizeof(a)&quo

C++空类默认函数详细解析

定义一个空的C++类,例如 class Empty{} 一个空的class在C++编译器处理过后就不再为空,编译器会自动地为我们声明一些member function,一般编译过去就相当于 复制代码 代码如下: class Empty{public:Empty(); // 缺省构造函数Empty( const Empty& ); // 拷贝构造函数~Empty(); // 析构函数Empty& operator=( const Empty& ); // 赋值运算符Empty* op

c语言获取文件大小的示例

1.fseek 函数原型: 复制代码 代码如下: int fseek ( FILE * stream, long int offset, int origin ); 参数说明:stream,文件流指针:offest,偏移量:orgin,原(始位置.其中orgin的可选值有SEEK_SET(文件开始).SEEK_CUR(文件指针当前位置).SEEK_END(文件结尾). 函数说明:对于二进制模式打开的流,新的流位置是origin + offset. 2.ftell 函数原型:long int ft

Linux 下C语言获取文件大小

Linux 下C语言获取文件大小 C语言是一种比较底层的语言,有时在其他语言中很容易操作的事情,在c语言中就比较麻烦,例如获取一个文件的大小.Java中File类有个length函数,Python中os.path包中有个getsize函数,C语言中却没有直接对应的函数获取文件大小. 目前,网上有一种流传很广的方法,读取文件到内存,然后跳转到文件末尾,查看跳转的长度.代码如下: int file_size(char* filename) { FILE *fp=fopen(filename,"r&q

asp下实现格式化文件大小以MB显示的函数

<% '****************************** '函数:FormatFileSize(l1) '参数:l1,字节数 '作者:阿里西西 '日期:2007/7/12 '描述:格式化文件大小样式 '示例:<%=FormatFileSize(l1)%> '****************************** function FormatFileSize(l1)  dim l2,l3  l3=formatnumber(l1,0,true)  if l1>104

Linux 改变文件大小的方法

函数原型: #include <unistd.h> int ftruncate(int fd, off_t length); //改变文件大小为length指定大小;返回值 执行成功则返回0,失败返回-1. 函数ftruncate会将参数fd指定的文件大小改为参数length指定的大小.参数fd为已打开的文件描述词,而且必须是以写入模式打开的文件.如果原来的文件大小比参数length大,则超过的部分会被删去. test.c #include<sys/types.h> #includ

python3获取url文件大小示例代码

在python3中,urllib2被替换为urllib.requeset,因此头文件中添加 import urllib.request as urllib2 def getRemoteFileSize(url, proxy=None): """ 通过content-length头获取远程文件大小 url - 目标文件URL proxy - 代理 """ opener = urllib2.build_opener() if proxy: if ur

用C语言获取文件的大小示例分享

查了一下发现同C语言的文件操作函数便可以很容易的实现这样的功能.在自己实现的函数中使用到的函数就只有fseek和ftell.它们的说明如下: fseek 语法: #include <stdio.h> int fseek( FILE *stream, long offset, int origin ); 函数fseek()为给出的流设置位置数据. origin的值应该是下列值其中之一(在stdio.h中定义): 名称 说明 SEEK_SET 从文件的开始处开始搜索 SEEK_CUR 从当前位置开

shell脚本实现统计文件大小、批量创建用户的示例

统计文件大小 需求: 每小时执行一次脚本,当时间为0点或12点时,清空/data/logs目录下所有日志文件的内容(包括该目录下的子目录里的文件),其他时间只需统计每个文件的大小,一个文件一行,记录到以日期和时间命名的文件中 #!/bin/bash dir=/data/log_size logdir=/data/logs d=`date +%d%H` t=`date +%H` #当目录不存在时创建记录文件存放目录 [ -d $dir ] || mkdir $dir #当记录文件存在时,先删除(避

jquery检测上传文件大小示例

本文实例讲述了jquery检测上传文件大小.分享给大家供大家参考,具体如下: google了很久,基本上都是用 activeX 来实现-至于为什么不行,这个不多说,说一下以下方法: 已经测试通过的浏览器:IE6+,firefox,chrome,其中 firefox 和 chrome 要能支持 HTML5. <html> <head> <meta http-equiv="Content-Type" content="text/html; chars

js获取上传文件大小示例代码

代码如下: 在ie下,貌似要改安全设置中的[对为标记为可安全执行脚本的ActiveX空间初始化并执行]那项 复制代码 代码如下: <html> <head> <script type="text/javascript"> var isIE = /msie/i.test(navigator.userAgent) && !window.opera; function fileChange(target) { var fileSize =

Spring Boot实现文件上传示例代码

使用SpringBoot进行文件上传的方法和SpringMVC差不多,本文单独新建一个最简单的DEMO来说明一下. 主要步骤包括: 1.创建一个springboot项目工程,本例名称(demo-uploadfile). 2.配置 pom.xml 依赖. 3.创建和编写文件上传的 Controller(包含单文件上传和多文件上传). 4.创建和编写文件上传的 HTML 测试页面. 5.文件上传相关限制的配置(可选). 6.运行测试. 项目工程截图如下: 文件代码: <dependencies>