The binding of the 3.1 data Member (the binding of a data Member) considers the following code:
A foo.h header file, from somewhere included in the extern float x;//Programmer's Point3d.h file class Point3D {public: Point3D (float, float, float); Question: What x is the x that is passed back and set? float x () const {return x;} void X (float new_x) const {x = new_x;} Private: float x, y, z;};
POINT3D::X () which x is passed back? Is it the x inside the class or the x outside (extern)? Now the answer is internal. But the answer to the past is not.
On the first compiler of C + +, if you refer to X in the two function instances of point3d::x (), this will point to the global X object. Such binding results are almost universal, and therefore derive the two defensive programming styles of early C + +:
1. Place all data members at the beginning of the class declaration to ensure proper binding:
Class pointed{ //Defensive programming style #1 //Start by placing all data members in the class declaration float x, y, z;public: float x () const {RET Urn x; } //...};
2. Place all inline functions, regardless of size, outside the class declaration:
Class Point3d{public: //Defensive programming style #2 //Move all inlines outside of Class pointed (); float X () const; void X (float) const; ...}; inline float point3d::x () const { return X;}
These procedural design styles are in fact still present today, and this ancient language rule is called "member rewriting rule" to the effect that "an inline function entity is not evaluated (evaluated) until the entire class declaration is not fully visible." The C + + standard refines This "rewriting rule" with "Member scope resolution rules", and the effect is that if an inline function is defined immediately after the class declaration, its evaluation is evaluated ( evaluated). In other words, if you write the following code:
extern int X;class Point3D {public: //The parsing of the function itself will be deferred until the closing parenthesis of the class declaration appears, starting with float x () const {return x;} Private: float x;};
For the analysis of member functions itself, it will not begin until the entire class declaration has occurred. Therefore, a data member binding operation within an inline member function occurs only after the entire class declaration is complete.
The 3.2 Data Member layout (data Member layout) is known as the following set of data members:
Class Point3D {public: //... private: float x; static List<point3d *> *freelist; float y; static const int chunkSize =; float Z;};
nonstatic data members are arranged in class object in the same order as they are declared, and any intervening static data Members such as Freelist and chunksize are not placed in the object layout. In the above example, each Point3D object is made up of three floats, in the order that the X,y,z.static data member is stored in the program's data Segment, independent of the individual class objects.
C + + standard requires that members be arranged in the same access section (that is, private,public,protected, etc.) to conform to "late-appearing members in class There is a higher address in the object "This is the condition. That is, the members do not have to be continuously arranged, what may be involved in the declaration of the members? The boundary adjustment (alignment) of the members may need to be populated with some bytes. For C and C For + +, this is true, which is true for the current C + + compiler implementation scenario.
The compiler might also synthesize some internally used data members to support the entire object model, which is what vptr is, and all of the current compilers insert it into every object that contains the virtual function class. Where will the vptr be placed? Traditionally it was placed at the end of all clearly declared members, but there are now some compilers that put vptr in the forefront of a class object. The C + + standard gives the layout a laissez-faire attitude, allowing the compiler to place the members that are created internally freely in any position, even between members that are declared by the programmer.
C + + Standard also allows the compiler to freely arrange data members in multiple access sections without caring about the order in which they appear in the class declaration, i.e., the following declaration:
Class Point3D {public: //... private: float x; Static List<point3d *> *freelist;private: float y; static const int chunkSize = 250;private: float z;};
Its class object is the same size and composition as the one previously declared, but the order of members is determined by the compiler.
The current compiler is a chain of more than one access sections, in the order of declarations into a contiguous block. The number of Access sections does not cause additional burdens, such as declaring 8 members in a section, or declaring a total of 8 members in 8 sections, resulting in the same object size.
The template function below accepts two data members, and then determines who appears first in class object. If two members are the first to be declared in a different access sections, This function can be used to determine which section appears first:
Template <class Class_type1, class Class_type2, Class Class_type3>char * Access_order (data_type1 class_type::* Mem1, data_type2 class_type::* mem2) { assert (mem1! = mem2); Return Mem1 < mem2? "Member 1 occurs first": "Member 2 occurs first";}
This function can be called as follows:
Access_order (&point3d::z, &point3d::y);
So Class_type will be bound to Point3D, and Data_type1 and data_type2 will be bound to float.
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Binding of the C + + object Model--data Member (chapter III)