[Reading Notes] In-depth exploration of the C++ object model - Chapter 1 "About Objects"

The latest is to explore the C++ object model (Inside C++ object model), and at the same time, I organize reading notes for some content that I did not pay attention to or did not understand deeply, so as to facilitate the review later, and I hope it can help people who have the same doubts.

The following is the content of the first chapter. Note: The following pictures are from the original book :

About Objects (Object Lessons)

1. The extra burden of C++ on layout and access time is caused by virtual.

This refers to the virtual function and virtual inheritance mechanism in C++. Virtual functions are the main means to achieve polymorphism in C++. Virtual inheritance is proposed to solve the problem of multiple repeated data such as diamond inheritance of classes above grandfather and classes below grandchildren. The content is introduced in the following chapters, and the subsequent notes will be organized in detail.

2. Several possible object models

a. Simple object model: All actual members are not stored in the space of the object itself, but in the form of pointers to the actual stored members in the object, although this model is not actually applied to the real C++ compiler, but about the index And the concept of the number of slots is applied to the C++ concept of "pointers to members" (pointers to members are discussed in detail in Chapter 3, which will be documented later).


b. Table-driven object model: This model is somewhat similar to the above model, but in this model, member information is divided into two parts, data members and member functions, although this model is not applied to the actual C++ compiler. , but the concept of member function table is the implementation of most virtual functions.


c. C++ object model: This is the object model currently used by the actual compiler. It is derived from Stroustrup through a simple object model. In this model, non-static members are configured in each class object, and static members are stored in the class Outside the object (static storage area), member functions (static and non-static) are also placed outside the class object. As for virtual functions, they are implemented through the following two steps: 1. Each class generates a bunch of pointers to virtual functions. The pointer is placed in a table, which is called a virtual table (virtual table: vtbl). Note that this virtual table is not placed in the class object. 2. Each class object will add a pointer (vptr) to the relevant virtual table. The setting and reset of the pointer will be automatically completed by the constructor, destructor, and copy constructor of the corresponding class. The associated type_info object (to support RTTI: runtime type identification) is usually stored in the first slot of the table. The advantage of this model is the efficiency of space and access time. The disadvantage is that if the non-static members of the class change, even if the client code does not change, the client code also needs to be recompiled.


A practical example, class X defines a copy constructor, a virtual destructor, and a virtual function foo(), then a typical X instantiation object has the following layout:


3. Regarding the size of the class object (there will be a detailed discussion later), in general, a class object should consider the sum of the size of all non-static members + any due to alignment (in order to ensure the highest efficiency of the bus traffic, the object The size will be adjusted upward to an integer multiple of a certain value. For 32bit machines, the value is usually 4 ) the space added by the operation + the additional burden to support the virtual (virtual) mechanism (pointer to the virtual table, pointing to the virtual pointer to the base class).

4. Regarding pointers (or references, because references are essentially implemented through pointers), from the point of view of memory requirements, a pointer to an integer and a pointer to an object, or a pointer to a template object , they are no different, their content is a machine address, pointing to pointers of different types, neither in the representation of their pointers, nor in their content (an address), but in the type of the object they address Different, that is, "pointer types" teach the compiler how to interpret the memory content and size at a particular address, and in C++, one way to use polymorphism is to use a pointer to a base class or a reference to a derived class , for example ZoomAnimal za("Joey");  ZoomAnimal* pza = &za; The current memory layout may be as follows:


The memory layout after adding polymorphism:




Guess you like

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