1、为何空类的大小不是0呢?
为了确保两个不同对象的地址不同,必须如此。
类的实例化是在内存中分配一块地址,每个实例在内存中都有独一无二的二地址。同样,空类也会实例化,所以编译器会给空类隐含的添加一个字节,这样空类实例化后就有独一无二的地址了。所以,空类的sizeof为1,而不是0.
2、请看下面的类:
class A{ virtual void f(){} };
class B:public A{}
此时,类A和类B都不是空类,其sizeof都是4,因为它们都具有虚函数表的地址。
3、请看:
class A{};
class B:public virtual A{};
此时,A是空类,其大小为1;B不是空类,其大小为4.因为含有指向虚基类的指针。
4、多重继承的空类的大小也是1.
class Father1{}; class Father2{};
class Child:Father1, Father2{};
它们的sizeof都是1.
5、何时共享虚函数地址表:
如果派生类继承的第一个是基类,且该基类定义了虚函数地址表,则派生类就共享该表首址占用的存储单元。对于除前述情形以外的其他任何情形,派生类在处理完所有基类或虚基类后,根据派生类是否建立了虚函数地址表,确定是否为该表首址分配存储单元。
======================================================================
你定义了一个空类后,其实空类里面会自动生成一些内容的
class Empty {
public: Empty(); // 缺省构造函数
Empty(const Empty& rhs); // 拷贝构造函数
~Empty(); // 析构函数 ---- 一般非虚的(除非继承体系有虚函数)
Empty &operator=(const Empty& rhs); // 赋值运算符
Empty* operator&(); // 取址运算符 const Empty* operator&() const;
};
不难解释为何要占一个字节。
换个角度,倘若你不给他分一个字节,在下面你继承这个空类的时候,从哪里确定有这个父类呢?
========================================================================
(一)
class CBase
{
};
sizeof(CBase)=1;
为什么空的什么都没有是1呢?
c++要求每个实例在内存中都有独一无二的地址。//注意这句话!!!!!!!!!!
空类也会被实例化,所以编译器会给空类隐含的添加一个字节,这样空类实例化之后就有了独一无二的地址了。所以空类的sizeof为1。
class CBase
{
int a;
char p;
};
sizeof(CBase)=8;
记得对齐的问题。int占4字节//注意这点和struct的对齐原则很像!!!!!
char占一字节,补齐3字节
(三)
class
{
public:
CBase(void);
virtual ~CBase(void);
private:
int
char *p;
};
再运行:sizeof(CBase)=12
C++类中有虚函数的时候有一个指向虚函数的指针(vptr),在32位系统分配指针大小为4字节。无论多少个虚函数,只有这一个指针,4字节。//注意一般的函数是没有这个指针的,而且也不占类的内存。
(四)
class CChild :public
{
public:
CChild(void);
~CChild(void);
virtual void test();
private:
int b;
};
输出:sizeof(CChild)=16;
可见子类的大小是本身成员变量的大小加上父类的大小。//其中有一部分是虚拟函数表的原因,一定要知道父类子类共享一个虚函数指针
(五)
#include<iostream.h>class a {};classb{};class c:public a{virtual void fun()=0;};class d:public b,publicc{};intmain(){cout<<"sizeof(a)"<<sizeof(a)<<endl;cout<<"sizeof(b)"<<sizeof(b)<<endl;cout<<"sizeof(c)"<<sizeof(c)<<endl;cout<<"sizeof(d)"<<sizeof(d)<<endl;return0;}程序执行的输出结果为:sizeof(a)=1sizeof(b)=1sizeof(c)=4sizeof(d)=8前三种情况比较常见,注意第四种情况。类d的大小更让初学者疑惑吧,类d是由类b,c派生迩来的,它的大小应该为二者之和5,为什么却是8呢?这是因为为了提高实例在内存中的存取效率.类的大小往往被调整到系统的整数倍.并采取就近的法则,里哪个最近的倍数,就是该类的大小,所以类d的大小为8个字节.总结:
空的类是会占用内存空间的,而且大小是1,原因是C++要求每个实例在内存中都有独一无二的地址。
(一)类内部的成员变量:
普通的变量:是要占用内存的,但是要注意对齐原则(这点和struct类型很相似)。static修饰的静态变量:不占用内容,原因是编译器将其放在全局变量区。