1、静态成员占多大?
一个空的class在内存中多少字节?如果加入一个成员函数后是多大?这个成员函数存储在内存中什么部分?
一个Class对象需要占用多大的内存空间。最权威的结论是:
- 非静态成员变量总合。
- 加上编译器为了CPU计算,作出的数据对齐处理。
- 加上为了支持虚函数,产生的额外负担。
(1)空类的Size
class Car { }; void main() {
Car objCar; cout << sizeof(objCar) << endl;//1 }
编译器在执行Car objCar;这行代码后需要,作出一个Class Car的Object。并且这个Object的地址还是独一无二的,于是编译器就会给空类创建一个隐含的一个字节的空间。
(2)只有成员变量的Size
class Car { private: int nLength; int nWidth; }; void main() { cout << sizeof(Car) << endl;//8 }
在32位系统中,整型变量占4个字节。这里Class Car中含有两个整型类型的成员变量,所以Class Size是8。
class Car { private: int nLength; int nWidth; static int sHigh; }; void main() { Car objCar; cout << sizeof(objCar) << endl;//8
我们这次在Class Car中添加了一个静态成员变量,但是Class Size仍然是8个字节。这正好符合了,结论中的第一条:非静态成员变量总合。
class Car { private: char chLogo; int nLength; int nWidth; static int sHigh; }; void main() { Car objCar; cout << sizeof(objCar) << endl;//12 }
在类中又插入了一个字符型变量,结果Class Size变成了12。这个就是编译器额外添加3个字符变量,做数据对齐处理,为了是提高CPU的计算速度。编译器额外添加的东西我们是无法看见的。这也符合了结论中的第二条:加上编译器为了CPU计算,作出的数据对齐处理。
既然,我们这样定义类成员数据编译器会额外的增加空。那么,我们何不在定义类的时候就考虑到数据对齐的问题,可以多定义出3个字符类型变量作为预留变量,既能满足数据对齐的要求,也给自己的程序添加了一些可扩展的空间。
(3)只有成员函数的Size
class Car { public: Car() {}; ~Car() {}; void Fun() {}; }; void main() { Car objCar; cout << sizeof(objCar) << endl;//1 }
噢,这是怎么回事儿呢?再做一个实验看看。
class Car { public: Car() {}; ~Car() {}; void Fun() {}; private: int nLength; int nWidth; }; void main() { Car objCar; cout << sizeof(objCar) << endl;//8
这次应该很清楚的了。函数是不占用类空间的。第一个例子中的Size为1个字节,正是编译器为类创建一个隐含的一个字节的空间。
class Car { public: Car() {}; virtual ~Car() {}; void Fun() {}; }; void main() { Car objCar; cout << sizeof(objCar) << endl;//4 }
这次,让析构函数为虚函数,看到了Class Size为4。这正是指向Virtual Table的指针vptr的Size。这正好符合了,结论中的第三条:加上为了支持虚函数,产生的额外负担。
#include <iostream> using namespace std; class C1 { public: int i;//4 int j;//4 char k;//4 };//12 class C2 { public: int i;//4 int j;//4 char k;//4 static int m; int getK() const { return k; } void setK(int val) { k = val; } }; struct S1 { int i;//4 int j;//4 char k;//4 };//12 struct S2 { int i;//4 int j;//4 char k;//4 static int m; };//12 int main() { cout << "C1:" << sizeof(C1) << endl; cout << "C2:" << sizeof(C2) << endl; cout << "S1:" << sizeof(S1) << endl; cout << "S2:" << sizeof(S2) << endl; return 0; }
2、处理机制
通过上面的案例,我们可以的得出:
C++类对象中的成员变量和成员函数是分开存储的。
成员变量:
普通成员变量:存储于对象中,与struct变量有相同的内存布局和字节对齐方式;
静态成员变量:存储于全局数据区中;
成员函数:存储于代码段中。
1、C++类对象中的成员变量和成员函数是分开存储的。C语言中的内存四区模
型仍然有效!
2、C++中类的普通成员函数都隐式包含一个指向当前对象的this指针。
3、静态成员函数、成员变量属于类。
4、静态成员函数与普通成员函数的区别:
静态成员函数不包含指向具体对象的指针;
普通成员函数包含一个指向具体对象的指针 。