sizeof finds the size of the class

Original address: https://blog.csdn.net/cy_cai/article/details/52979402

How much space does an instantiated object of a class occupy? Be careful not to say the size of the class, but the size of the object of the class. 
First, what is the size of the class? To be precise, a class is just a type definition, it has no size to speak of. Use the sizeof operator to operate on a type name, and get the size of an entity with that type. add charles empty structure: sizeof of struct d{} is also 1. 
if

Class A; A obj; 

Then sizeof(A)==sizeof(obj) So what is the relationship between the size of sizeof(A) and the sum of the size of the members, very simple, the size of an object is greater than or equal to the sum of the sizes of all non-static members. 
Why is greater than or equal and not exactly equal? The excess part mainly includes the following two aspects: 
1) The C++ object model itself needs a method to provide type information (RTTI) and virtual function entry for its entity for the type with virtual function. The common method is to create a virtual function. Function entry table. This table can be shared by objects of the same type, so there needs to be a pointer to the virtual function table in the object. In addition, in order to support RTTI, many compilers put the type information in the virtual function table. However, whether this implementation method must be adopted is not stipulated by the C++ standard, but these are a scheme adopted by mainstream compilers. 
2) Compiler optimization Because for most CPUs, the integer multiple of the CPU word length operates faster, so if these members are not added up to this integer multiple, it is possible that the compiler will insert extra content to make up this integer multiple. , in addition, sometimes adjacent members may also be inserted blanks for this purpose, which is called "padding". Therefore, the C++ standard strictly stipulates that members are arranged in the order in which the class is defined, but it is not required to be closely arranged in memory. 
Based on the above two points, it can be said that using sizeof to operate on the class name, the result obtained is the size of bytes occupied by the object of the class in the memory. Since the static member variable is not stored in the object, the result is equal to the non-static data member. (excluding member functions) plus the extra bytes added by the compiler. The latter relies on different compiler implementations, which the C++ standard makes no guarantees about. 
The C++ standard stipulates that the size of a class is not 0, the size of an empty class is 1, and when a class does not contain virtual functions and non-static data members, its object size is also 1. If a virtual function (whether one or more) is declared in the class, then when the object is instantiated, the compiler will automatically insert a pointer to the virtual function table VTable in the object. On a 32-bit machine, an object will Add 4 bytes to store this pointer, which is the key to implementing polymorphism in object orientation. The virtual function itself, like other member functions, does not occupy the space of the object. Let's take a look at the following example: (This example is compiled and run in the Visual C++ compiler)

#include <iostream>
using namespace std;
class A { };
class B {
char ch;
void func() { }
};
class C {
char ch1; //占用1字节
 char ch2; //占用1字节
 virtual void func() { }
};
class D {
 int in;
 virtual void func() { }
};
 void main() {
A a;
B b;
C c;
D d;
cout<<sizeof(a)<<endl;//result=1   
cout<<sizeof(b)<<endl;//result=1   //对象c扩充为2个字,但是对象b为什么没扩充为1个字呢(空类的对象一个字节,含一个char的类类对象也为一个字节。)?因为B类只有一个成员变量,普通成员函数不占用内存。
cout<<sizeof(c)<<endl;//result=8   
//对象c实际上只有6字节有用数据,但是按照上面第二点编译器优化,编译器将此扩展为两个字(add charles 字节对齐),即8字节
cout<<sizeof(d)<<endl;//result=8   
}  

To sum up: In 
a class, virtual functions, member functions (including static and non-static) and static data members do not occupy the storage space of class objects. 
Object size = vptr (there may be more than one, this is difficult to determine, but tried, a virtual function is defined in the class, still occupying 4 bytes) + the size of all non-static data members + the size of Aligin bytes (depending on different compiler)

c++ empty class instance size is not 0 reasons?  
Beginners have more or less doubts when learning object-oriented programming languages. The code we write is very different from the final compiled code, and we don't know what the compiler does in the background. These are all due to the fact that we only stay at the language level, which teaches us some basic grammar rules, but does not tell us why we do it? A little insight that I talk to you about today is my experience in the process of learning programming, and it is a specific function of the compiler. 
First of all: we need to know what is instantiation of a class. The so-called instantiation of a class is to allocate an address in memory. 
So let's take a look at an example:

#include<iostream.h>
class a {};
class b{};
class c:public a{
 virtual void fun()=0;
};
class d:public b,public c{};
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)=1
sizeof(c)=4
sizeof(d)=8 #charlse# 这里错误,这个调试中是4

#charles#下列是例子
#include <iostream>
using namespace std;

class a {};
class b1{};
class b{
char a;
};
class c:public a{
 virtual void fun()=0;
};
class d:public b,public c{};
class e:public b1,public c{};
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;#这种情况是8
 cout<<"sizeof(e)"<<sizeof(e)<<endl;#这种情况是4
 return  0;
}

Why does this result occur? Beginners must be very annoying, right? Class a and b are clearly empty classes, and their size should be 0. Why does the compiler output the result as 1? This is why we just mentioned instantiation (empty classes can also be instantiated), each instance has a unique address in memory, for this purpose, compilers often give an empty class an implicit address Add a byte so that the empty class gets a unique address in memory after instantiation. So the size of a and b is 1. 
And class c is derived from class a, it has a pure virtual function in it, because of the virtual function, there is a pointer to the virtual function (vptr), the size of the pointer allocated to the 32-bit system is 4 bytes, so the final size of class c is 4. 
The size of class d is even more confusing for beginners. Class d is derived from classes b and c. Its size should be the sum of the two and 5, why is it 8? This is because to improve the access efficiency of instances in memory. Class sizes are often adjusted to integer multiples of the system. And take the nearest rule, the nearest multiple is the size of the class, so the size of class d is 8 bytes. 
Of course, the results obtained on different compilers may be different, but this experiment tells us beginners that no matter whether the class is empty or not, it can be instantiated (empty classes can also be instantiated), and each instance has a Unique address. 
The compiler I use is vc++ 6.0.

Let's look at another example below.

#include<iostream.h>
class a{
pivate: 
int data;
};
class b{ 
private:
     int data;
  static int data1;
};
 int b::data1=0;
 void mian(){
 cout<<"sizeof(a)="<<sizeof(a)<<endl;
 cout<<"sizeof(b)="<<sizeof(b)<<endl;
}

The execution result is:

sizeof(a)=4;
sizeof(b)=4;

Why does class b have one more data member, but the size is the same as that of class a? Because: the static data member of class b is placed in a global data member of the program by the compiler, which is a data member of the class. But it does not affect the size of the class, no matter how many instances the class actually generates or how many new classes are derived, the static member data will always only have one entity in the class, and the non-static data members of the class will only be instantiated when , they exist. But once a static data member of a class is declared, it exists whether the class is instantiated or not. It can be said that a static data member of a class is a special kind of global variable. 
So a and b are the same size.

Let's look at the size of a class with a constructor and a destructor. How big is it?

#include<iostream.h>
class A{
public :
 A(int a){
  a=x;}
 void f(int x){
  cout<<x<<endl;}
 ~A(){}
private:
   int x;
   int g;
   };
class B{
public:
 private:
 int  data; int data2;
 static int xs;
};
int B::xs=0;
void  main(){
 A s(10);
 s.f(10);
 cout<<"sozeof(a)"<<sizeof(A)<<endl;
 cout<<"sizeof(b)"<<sizeof(B)<<endl;
}

The output of the program execution is:

sizeof(a) 8
sizeof(b) 8

Their results are the same, it can be seen that the size of the class has nothing to do with its constructors, destructors, and other member functions, but only with its member data. 
It is not difficult to find the size of the class from the above examples: 
1. is the sum of the type sizes of the non-static member data of the class. 
2. The size of additional member variables added by the compiler to support certain features of the language (eg, pointers to virtual functions). 
3. In order to optimize the access efficiency, the edge adjustment (byte alignment) is carried out. 
4 has nothing to do with the constructor, destructor and other member functions in the class.


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325933637&siteId=291194637