C + + object model--object construction in the case of "No Inheritance" (fifth chapter)

Source: Internet
Author: User

5.1 Object construction in the case of "no inheritance"Consider the following program fragment:
1Point global;23point foobar () 4{5point local;6point *heap = new Point;7*heap = local;8/ /... stuff ... 9delete Heap;10return Local;11}
L1,l5,l6 shows three different ways to produce objects : Global memory configuration, local memory configuration, and heap memory configuration. L7 assigns a class object to another, L10 sets the return value, and L9 explicitly deletes the heap object with the delete operator.
The life of an object is a period of execution of the object, where the life of thelocal object begins with the definition of L5, and until L10. Global Object Lives the same life as the entire program. the life of the heap object begins when it is configured by the new operator until it is destroyed by the delete operator.
Here is the first statement of point, which can be written as a C program. C + + standard says this is a so-called plain of data declaration form:
typedef struct {Float x, y, Z;} Point;
What happens if I compile this code in C + +? In concept, the compiler will declare a trivial default constructor for point, a trivial destructor, a trivial copy constructor, and a trivial copy assignment operator. But actually the compiler parses the entire declaration and stickers it with the plain of data tag.
When the compiler encounters such a definition:
1 point Global;
, the trivial constructor and destructor of point are generated and called. constructor is called at the beginning of the program (startup) and destructor is called at exit () of the Program (exit () is generated by the system and placed before main ().However, the fact that the trivial members were not defined, or were not invoked, acted as if it were in C.
in C, Global is considered a "temporary definition", because it does not have an explicit initialization operation, a "temporary definition" can occur multiple times in the program. Those instances are collapsed by the linker, leaving only a single entity, placed in the program data segment, a "special reserved for the initialized global objects use" space.
C + + does not support "temporal definition" because of the implicit application of class construction behavior. Global is considered fully defined in C + +. All global objects in C + + are treated as "initialized data."
The L5 in the Foobar () function has a point object local, which is neither constructed nor deconstructed. The point Object local may become a potential program if it is not initialized first bug--in case it needs its initial value (such as L7) for the first time.As for the initialization of the heap object in L6:
Point *heap = new Point;
will be converted to a call to the new operator (provided by the library):
Point *heap = __new (sizeof (point));
again, there is no default constructor execution on the point object returned by the new operator.L7 has an assignment (assignment, assign) to this object, and if local has been properly initialized, there is no problem.
7 *heap = local;
In fact, this line will produce a compiler warning as follows:
Warning,line 7:local is used before being initialized.
The notion that such a specified operation triggers trivial copy assignment operator for copy handling. However, this object is actually a plain of Data, so the assignment operation (Assignment) Will just be a purely bit-handling operation like C, L9 performs a delete operation:
9 Delete heap;
will be converted to a call to the delete operator (provided by Libraray):
__delete (heap);
The idea is that such an operation would trigger the trivial destructor of point. But destructor is either not being produced or not being called. Finally, the function returns the local as a return value in the way of value (by value), This will trigger trivial copy constructor, but actually the extern operation is just a simple bit copy operation because the object is a plain of Data.

Abstract data typeThe following is the second declaration of Point, which has more private data under the public interface, provides complete encapsulation, but does not provide any virtual function:
Class Point {Public:point (float x = 0.0, float y = 0.0 float z = 0.0): _x (x), _y (y), _z (z) {}//No copy constructor, copy operator or destructor defined ... private:float _x, _y, _z;};
This encapsulated point class, its size does not change, or three consecutive floats, yes, no matter the private,public access layer, or the member function declaration, will not occupy additional object space.
a copy constructor or copy operator is not defined for point because the default bit semantics(Default bitwise semantics, chapter II, page 51) It's enough. There is no need to provide a destructor because the default memory management method for the program is sufficient.
For a global entity:
Point global;//implementation point::P oint (0.0, 0.0, 0.0);
Now with the default constructor on it, because global is defined in the global context, its initialization will be delayed until program activation (see section 6.1)
If you want to set a constant value for all members of class, then giving a explicit initialization list is more efficient. Even in the local scope.For example, consider the following program fragment:
void mumble () {Point local1 = {1.0, 1.0, 1.0}; Point local2;//is equivalent to an inline expansion//explicit initialization will be slightly faster local2._x = 1.0;local2._y = 1.0;local2._z = 1.0;}
Local1 initialization is more efficient than Local2,since the activation recored of the function is put into the program stack, the constants in the initialization list above can be put into local1 memory.
The explicit initialization list brings three drawbacks:
1. This method works only if the class members are public.
2. Constants can only be specified because they are evaluated at compile time.
3. The failure of the initialization behavior may be higher because the compiler is not automatically implemented.
can the efficiency benefits of the explicit initialization list compensate for its drawbacks in software engineering?
Generally speaking, the answer is no. However, in some special cases, it is not the same. For example, perhaps by hand creating some huge data structures such as palette, or is about to dump a bunch of constant information to the program, then Explicit initialization list is much more efficient than inline constructor, especially for global objects.
At the compiler level, an optimization mechanism is used to identify the inline constructor, which simply provides a Member-by-member constant specifying the operation, and the compiler extracts those values and treats them as if they were explicit Initialization list does not extend the constructor into a series of assignment instructions.
Thus, the local point object is defined as:
{point Local;}
Now attached to the default point constructor's inline expansion:
{//inline expansion of default Constructorpoint local;local._x = 0.0;local._y = 0.0;local._z = 0.0;}
The L6 configures a heap point object:
6Point *heap = new Point;
A conditional invoke operation on default point constructor is now attached:
Point *heap = __new (sizeof), if (heap! = 0) Heap->point::P oint ();
Then the inline expansion operation is performed by the compiler, and the heap pointer is pointed to the local object:
7*heap = local;
The same is true for this simple bit copy operation, which is passed back to the local object in a value-based manner:
10return Local;
L9 delete the object that the heap refers to:
9delete Heap;
This operation does not cause destructor to be called because it does not explicitly provide a destructor function entity.
In concept, point class has a related default copy constructor,copy operator and destructor, howeverthey are irrelevant, and the compiler doesn't actually produce them at all.

Prepare for inheritanceThe third point declares that it will prepare for the "inherited nature" and the dynamic resolution of some operations (resolution) when restricting access to the Z-member:
Class Point {Public:point (float x = 0.0, float y = 0.0): _x (x), _y (y) {}//no destructor, copy constructor, or copy opera Tor defined: Virtual float z ();p rotected:float _x, _y;};
Again, there is no definition of a copy constructor,copy Operator,destructor. All members are accessed by value, so they behave well under the default semantics at the program level.
the import of virtual functions prompts each point object to have a virtual table Pointer. This pointer provides the flexibility of the virtual interface, The price is: Each object requires an extra word space.What's the big impact?depending on the application, it must be based on the proportion of the actual benefit that it brings to the polymorphic design.
In addition to each class object that burdens a vptr, the introduction of virtual functions also causes the compiler to inflate the point class:
The defined constructor is appended with some code to initialize the vptr. These codes must be appended to any base class constructor call, but must precede any code supplied by the user (programmer). For example, here are the possible additional results:
Point *point::P oint (Point *this, float x, float y): _x (x), _y (y) {//Virtual table pointer (vptr) Setting object This->__vptr_ Point = __vtbl__point;//Extension member Initialization listthis->_x = X;this->_y = y;//returns this object return this;}
synthesizes a copy constructor and a copy assignment operator, and its operation is no longer trivial (but implicit destructor is still trivial). If a point object is initialized or assigned with a derived class object, the bitwise-based (bitwise) operation may cause vptr to be illegally set.
Copy Constructor's internal composition inline point* point::P oint (Point *this, const point &RHS) {//virtual table pointer with object Set (V PTR) This->__vptr_point = __vtbl__point;//copies the contiguous bits in the RHS coordinates to the This object, or provides a assignment via member member ... return this;
the compiler may copy the continuous contents of object to another object in an optimized state, without implementing an exact "member-based" assignment operation. C + + standard requires the compiler to delay the actual synthesis of nontrivial memebrs as much as possible until it actually encounters its usage situation.
1Point global;23point foobar () 4{5point local;6point *heap = new Point;7*heap = local;8/ /... stuff ... 9delete Heap;10return Local;11}
The L1 global initialization operation, the L6 heap initialization operation, and the L9 heap delete operation are still the same as the earlier point version, but the memberwise assignment operation for L7:
*heap = local;
It is likely to trigger the composition of the copy assignment operator, as well as an inline expansion (internal extension) of its invocation operation, replacing the heap with this and replacing local with RHS.


Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

C + + object model--object construction in the case of "No Inheritance" (fifth chapter)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.