Determining the Size of a Class Object---sizeof(class)---By Girish Shetty
There are many factors that decide the size of an object of a class in C++. These factors are:
- Size of all non-static data members
- Order of data members
- Byte alignment or byte padding
- Size of its immediate base class
- The existence of virtual function(s) (Dynamic polymorphism using virtual functions).
- Compiler being used
- Mode of inheritance (virtual inheritance)
Size of all non-static data members
Only non-static data members will be counted for calculating sizeof class/object.
class A {
private:
float iMem1;
const int iMem2;
static int iMem3;
char iMem4;
void func(); //函数不占用class大小
};
For an object of class A, the size will be the size of float iMem1 + size of int iMem2 + size of char iMem4. Static members are really not part of the class object. They won't be included in object's layout.
Order of data members
The order in which one specifies data members also alters the size of the class.
class C {
char c;
int int1;
int int2;
int i;
long l;
short s;
};
The size of this class is 24 bytes. Even though char c will consume only 1 byte, 4 bytes will be allocated for it, and the remaining 3 bytes will be wasted (holes). This is because the next member is an int, which takes 4 bytes. If we don't go to the next (4th) byte for storing this integer member, the memory access/modify cycle for this integer will be 2 read cycles. So the compiler will do this for us, unless we specify some byte padding/packing.
If I re-write the above class in different order, keeping all my data members like below:
class C {
int int1;
int int2;
int i;
long l;
short s;
char c;
};
Now the size of this class is 20 bytes.
In this case, it is storing c, the char, in one of the slots in the hole in the extra four bytes.
Byte alignment or byte padding
As mentioned above, if we specify 1 byte alignment, the size of the class above (class C) will be 19 in both cases.
Size of its immediate base class
The size of a class also includes size of its immediate base class.
Let's take an example:
Class B {
...
int iMem1;
int iMem2;
} Class D: public B {
...
int iMem;
}
In this case, sizeof(D) is will also include the size of B. So it will be 12 bytes.
The existence of virtual function(s)
Existence of virtual function(s) will add 4 bytes of virtual table pointer in the class, which will be added to size of class. Again, in this case, if the base class of the class already has virtual function(s) either directly or through its base class, then this additional virtual function won't add anything to the size of the class. Virtual table pointer will be common across the class hierarchy. That is
class Base {
public:
...
virtual void SomeFunction(...);
private:
int iAMem
}; class Derived : public Base {
...
virtual void SomeOtherFunction(...);
private:
int iBMem
};
In the example above, sizeof(Base) will be 8 bytes--that is sizeof(int iAMem) + sizeof(vptr). sizeof(Derived) will be 12 bytes, that is sizeof(int iBMem) + sizeof(Derived). Notice that the existence of virtual functions in class Derived won't add anything more. Now Derived will set the vptr to its own virtual function table. (不管类里有几个虚函数,都只有一个虚函数表)
Compiler being used
In some scenarios, the size of a class object can be compiler specific. Let's take one example:
class BaseClass {
int a;
char c;
}; class DerivedClass : public BaseClass {
char d;
int i;
};
If compiled with the Microsoft C++ compiler, the size of DerivedClass is 16 bytes. If compiled with gcc (either c++ or g++), size of DerivedClass is 12 bytes.
The reason for sizeof(DerivedClass) being 16 bytes in MC++ is that it starts each class with a 4 byte aligned address so that accessing the member of that class will be easy (again, the memory read/write cycle).
Mode of inheritance (virtual inheritance)
In C++, sometimes we have to use virtual inheritance for some reasons. (One classic example is the implementation of final class in C++.) When we use virtual inheritance, there will be the overhead of 4 bytes for a virtual base class pointer in that class.
class ABase{
int iMem;
}; class BBase : public virtual ABase {
int iMem;
}; class CBase : public virtual ABase {
int iMem;
}; class ABCDerived : public BBase, public CBase {
int iMem;
};
And if you check the size of these classes, it will be:
- Size of ABase : 4
- Size of BBase : 12
- Size of CBase : 12
- Size of ABCDerived : 24
Because BBase and CBase are derived from ABase virtually, they will also have an virtual base pointer. So, 4 bytes will be added to the size of the class (BBase and CBase). That is sizeof ABase + size of int + sizeof Virtual Base pointer.
Size of ABCDerived will be 24 (not 28 = sizeof (BBase + CBase + int member)) because it will maintain only one Virtual Base pointer (Same way of maintaining virtual table pointer).
--------------------------------------
类的实例化,所谓类的实例化就是在内存中分配一块地址,每个实例在内存中都有独一无二的地址。同样空类也会被实例化(别拿豆包不当干粮,空类也是类啊),所以编译器会给空类隐含的添加一个字节,这样空类实例化之后就有了独一无二的地址了。所以空类的sizeof为1。
{
};
运行cout<<"sizeof(CBase)="<<sizeof(CBase)<<endl;
sizeof(CBase)=1;
------------------------------------------
To a first order approximation, the size of an object is the sum of the sizes of its constituent data members. You can be sure it will never be smaller than this.
More precisely, the compiler is entitled to insert padding space between data members to ensure that each data member meets the alignment requirements of the platform. Some platforms are very strict about alignment, while others (x86) are more forgiving, but will perform significantly better with proper alignment. So, even the compiler optimization setting can affect the object size.
Inheritance and virtual functions add an additional complication. As others have said, the member functions of your class themselves do not take up "per object" space, but the existence of virtual functions in that class's interface generally implies the existence of a virtual table, essentially a lookup table of function pointers used to dynamically resolve the proper function implementation to call at runtime. The virtual table (vtbl) is accessed generally via a pointer stored in each object.
Derived class objects also include all data members of their base classes.
-----------------------------------------------------
Methods belong to the class, not any particular instantiated object.
Unless there are virtual methods, the size of an object is the sum of the size of its non-static members, plus optional padding between the members for alignment. The members will probably be laid out sequentially in memory, but the spec doesn't guarantee ordering between sections with different access specifications, nor ordering relative to the layout of superclasses.
With virtual methods present, there may be additional space taken for vtable and other RTTI information.
-----------------------------------------------------------
class A{
int a1;
char* p;
public:
virtual void SomeFunction();
virtual void SomeFunction2();
void func();
};
class B:A{
int b;
virtual void SomeFunction3();
};
cout<<sizeof(A)<<" "<<sizeof(B)<<endl; //输出为 12 16
-------------------------------------------------------------
附录:
http://www.cprogramming.com/tutorial/size_of_class_object.html
http://stackoverflow.com/questions/937773/how-do-you-determine-the-size-of-an-object-in-c
http://blog.csdn.net/lishengwei/article/details/2416554
Determining the Size of a Class Object---sizeof(class)---By Girish Shetty的更多相关文章
- C语言中的sizeof()
sizeof,一个其貌不扬的家伙,引无数菜鸟竟折腰,小虾我当初也没少犯迷糊,秉着"辛苦我一个,幸福千万人"的伟大思想,我决定将其尽可能详细的总结一下. 但当我总结的时候才发现,这个 ...
- 数组类型与sizeof与指针的引用
以char类型为例: char a[100]; //a类型为char[100] &a类型为 char (*)[100] *a类型为char char *p = a; ...
- 全面总结sizeof的用法(定义、语法、指针变量、数组、结构体、类、联合体、位域位段)
一.前言 编译环境是vs2010(32位). <span style="font-size:18px;">#include<iostream> #inclu ...
- sizeof进行结构体大小的判断
typedef struct{ int a; char b;}A_t;typedef struct{ int a; char b; char c;}B_t;typedef ...
- Super Object Toolkit (支持排序)
(* * Super Object Toolkit * * Usage allowed under the restrictions of the Lesser GNU General Public ...
- java.sizeOf
Introduction With java.SizeOf you can measure the real memory size of your Java objects. Download it ...
- C++结构体中sizeof(1)
sizeof sizeof操作符的作用是返回一个对象或类型名的长度,长度的单位是字节. 返回值的类型是标准库命名为size_t的类型,size_t类型定义在cstddef头文件中,该头文件是C标准库的 ...
- 深刻理解void,void*和sizeof关键字
void的字面值是“无类型”,void*则是"无类型指针".void*可以指向任何类型的数据.void几乎只有"注释"和限制程序的作用,因为从来没有人会定义一个 ...
- sizeof,终极无惑(上)
0. 前向声明 sizeof,一个其貌不扬的家伙,引无数菜鸟竟折腰,小虾我当初也没少犯迷糊,秉着“辛苦我一个,幸福千万人”的伟大思想,我决定将其尽可能具体的总结一下. 但当我总结的时候才发现,这个问题 ...
随机推荐
- 如何申请新浪SAE,发布自己的网站
你是否会看见诸如(***.sinaapp.com)类的域名?是否和新浪有什么关系?抑或想要一个免费的空间展示自己的个人主页;没问题,下面我来分享一下SAE的申请流程吧! 首先,打开SAE(http:/ ...
- 670. Maximum Swap 允许交换一个数 求最大值
[抄题]: Given a non-negative integer, you could swap two digits at most once to get the maximum valued ...
- tomcat安装后,双击start.bat闪退的问题
1.jdk环境变量没有配 解决方案:我的电脑-属性-高级-环境变量,新增下面三个环境变量: ①JAVA_HOME=C:\Program Files\Java\jdk1.7.0_09(就是你jdk安装的 ...
- QScopedPointer
QScopedpointer detailed description the QScopedpointer class stores a pointer to a dynamically alloc ...
- opencv在64位4418上的移植
1.mkdir build 2.cmake-gui 操作系统写Linux 去掉 去掉WITH_CUDA 去掉WITH_GTK 去掉WITH_1394 去掉WITH_GSTREAMER 去掉WITH_L ...
- windows编程之内核对象
学好windows编程,理解内核对象还是至关重要的(●'◡'●).闲话不多说,下面先来了解一下关于内核对象的知识: 内核对象(kernel object):内核对象是用于管理进 ...
- JAVA 上加密算法的实现用例,MessageDigest介绍
第 1 章基础知识 1.1. 单钥密码体制 单钥密码体制是一种传统的加密算法,是指信息的发送方和接收方共同使用同一把密钥进行加解密. 通常 , 使用的加密算法 比较简便高效 , 密钥简短,加解密速度快 ...
- if-return 语句
if(A > B): return A+1 return A-1 or if(A > B): return A+1 else: return A-1 +++++++++++++++++++ ...
- STREAMING #5 题解 3.高位网络
高维网络 [题目描述] 现在有一个 d 维的坐标网格,其中第 i 维坐标的范围是[0,a_i].在这个范围内建立一个有向图:我们把范围内的每个整点(每一维坐标均为整数的点)当做图上的顶点.设点 A(0 ...
- 常用的 Python 调试工具,Python开发必读-乾颐堂
以下是我做调试或分析时用过的工具的一个概览.如果你知道有更好的工具,请在评论中留言,可以不用很完整的介绍. 日志 没错,就是日志.再多强调在你的应用里保留足量的日志的重要性也不为过.你应当对重要的内容 ...