在C语言中存在关于结构体的存储空间巨细是比较深化的论题,其间触及核算机的基本原理、操作体系等。我以为对齐是C语言中让许多初学者都拿不准摸不透的问题,特别是在跨渠道的状况下,对齐这种问题愈加的复杂多变,每一种体系都有自己共同的对齐方法,在Windows中经常是以结构体重最大内置类型的存储单元的字节数作为对齐的基准,而在Linux中,一切的对齐都是以4个字节对齐。
那么在C++中的类的内存空间巨细又有哪些特别的问题呢?
首要,我以为对齐必定也是其间的问题之一,对齐首要是为了加速读取的速度。
关于对齐这个我以为基本上现已是操作体系内定好的,已然Linux与Windows存在不同,那么在C++的类中,关于对齐必定也会存在必定的不同。关于对齐我以为只需记住平常运用的体系的对齐原则就能够了,即:在Windows中经常是以结构体重最大内置类型的存储单元的字节数作为对齐的基准,而在Linux中,一切的对齐都是以4个字节对齐。
其次,我以为就应该评论在基类中哪些成员占有存储空间,那些成员不占用内存空间?
在C++中占存储区间的首要对错static的数据目标,首要包括各种内置的数据类型,类目标等,类中的函数声明以及函数界说都不算内存空间。可是需求留意一切的virtual函数(虚函数)同享一段内存区域,一般来说是4个字节。为什么仅仅包括非static数据目标呢?因为static数据并不归于类的任何一个目标,它是类的特点,而不是详细某一个目标的特点,在整个内存区域中只要一个内存区域存储对应的static数据,也便是一切的类目标同享这个数据,所以不能当作详细某一个目标或许类型的内存空间。
因而能够以为基类目标的存储空间巨细为:
非static数据成员的巨细 + 4 个字节(虚函数的存储空间)
当然这个巨细不是一切数据成员巨细的叠加,而是存在一个对齐问题,详细的应该参阅相关的对齐文章。
最终,我以为必定要关怀一下派生类的存储空间了?
在C++中,承继类是一个比较有用的类,承继使得各品种在基类的基础上扩展,这时候派生类中包括了基类的信息,一般来说,在基类中存在虚函数时,派生类中承继了基类的虚函数,因而派生类中现已承继了派生类的虚函数。因而承继类中不能再增加虚函数的存储空间(因为一切的虚函数同享一块内存区域),而仅仅需求考虑派生类中心增加进来的非static数据成员的内存空间巨细。
因而能够以为派生类目标的存储空间巨细为:
基类存储空间 + 派生类特有的非static数据成员的存储空间
还有一类是比较特别的状况,如果是虚承继的状况下,这时的存储空间巨细就会发生变化。
基类的存储空间 + 派生类特有的非static数据成员的存储空间 + 每一个类的虚函数存储空间。
下面我选用一些比如阐明上面的问题:
对齐的问题:
class test
{
public:
test();
private:
int a;
char c;
};
cout << sizeof(test) << endl;
上面的代码在linux以及windows下都会输出8,而不是输出5,这个是在C语言中现已评论过的论题,可是阐明对齐在C++中也是要考虑的。关于操作体系的差异在后边用一个一致的比如阐明。
虚函数问题
为了评论虚函数,咱们在test类中增加一个虚析构函数,然后再测验成果。
class test
{
public:
test();
virtual ~test();
private:
int a;
char c;
};
cout << sizeof(test) << endl;
这段代码与前面的代码没有什么区别,仅仅增加了一个虚函数,然后编译调试,这时候输出的成果12,也便是说增加了一个虚函数今后,类的数据成员增加了4个字节,那么是否是每一个虚函数都占有4个字节呢?其实是不会的,在test中参加一个新的虚函数virtual void get_a_c(),这时在输出的成果仍是12,这阐明一切的虚函数同享4个字节。
static数据
咱们知道static数据对错目标的特点,而是类的特点,他不能算是某一个目标或许类型的存储空间,在类界说中只能声明,初始化只能在类外履行,当然有破例的。这也不做剖析了。详细参看后边的大比如。
派生类的存储空间
派生类从基类中承继了许多成员,自己也会增加许多的成员,因为虚函数也会被承继下来,所以便是在派生类中不显式界说虚函数,在派生类中也会存在从基类承继下来的虚函数,因而虚函数不需求额定核算内存空间,而只需求增加基类的非static成员数据巨细。界说如下面所示,该函数会输出20,刚好是增加的非static数据doubled的存储空间巨细。证明了上面的剖析。
class test
{
public:
test();
virtual ~test();
virtual void get_a_c();
private:
int a;
char c;
};
class derived_test:public test
{
public:
virtual ~derived_test();
private:
doubled ;
};
cout << sizeof(derived_test) << endl;
测验虚承继的类的巨细:
class A
{
char i[3];
public:
virtual void a(){};
};
class B : public virtual A
{
char j[3];
public:
virtual void b(){}
};
class C: public virtual B
{
char k[3];
public:
virtual void c(){}
};
int main()
{
cout << "sizeof(A): " << sizeof(A) << endl;
cout << "sizeof(B): " << sizeof(B) << endl;
cout << "sizeof(C): " << sizeof(C) << endl;
return 0;
}
下面选用一个比较归纳的比如阐明一下操作体系以及各种归纳的影响剖析。