C + + Lone Nine sword five--Life Geometry (object copy control)

Source: Internet
Author: User
Tags class definition shallow copy

complaining, the geometry of life? For example, the morning dew, daycare bitter.

human life may be stormy, more likely to be calm, this time we will discuss the "object" (of course, the students themselves are not within the scope of this discussion O (∩_∩) O, discuss it yourself after Class) life's "Up and down", that is, the object of replication control.

replication control consists of three parts: the invocation of a copy constructor, the invocation of an assignment operator, and the invocation of a destructor. The following three operations to each of the introduction, we learn together (*^-^*)

First, copy Constructor

Copy constructor: First it is also a constructor, so the function name is the same as the class name, there is no return value, and second, it has only one parameter, and the parameter is a reference to the object of this class type (commonly used const adornments).

Why do the parameters of a copy constructor need to be referenced? Let's look at the invocation scenario of the complex constructor :

1. When you display or implicitly initialize another object with one of the same-like objects.

2. Copy an object and pass it as an argument to the function.

3. When returning an object from a function.

4. When initializing elements in a sequential container.

5. When initializing an array element based on an element initializer list.

Assume that the parameter of the copy constructor is an object of that class type, not a reference. So when we pass an argument to a function (which is the same thing in other cases), the copy constructor is called implicitly, and the copy constructor itself requires the argument of the class object, and the copy constructor of the class is called! This will form the "dead loop" of the function call.

initialization and assignment may not be an easy thing to distinguish for beginners, so let me give you a little explanation. Initialization is the setting of values at the same time that the class object is formed, and the assignment is the setting of the value of the object after it is formed (here we treat the operation in the same statement as a simultaneous operation, though not from a microscopic point of view).

Let's say the following code calls:

{

A a1 = a2;//a2 also is Class A Object , the object A1 is set at the same time as the value is formed, so the copy constructor is called because this is the initialization operation.

}

{

A A1;

A1 =a2;// The assignment operator function is called at this point because it is no longer initialized.

}

Like the default constructor, C + + standard says that if a copy constructor is not declared in a class, an implicit declaration or definition occurs. But the copy constructor will be divided into trivial and nontrivial, in fact, only nontrivial when the compiler will synthesize the corresponding functions (many times it is, habits are good). Furthermore,C + + standard requires the compiler to delay the actual synthesis of nontrivalmembers until it actually encounters its usage situation.

So when does the compiler actually synthesize the copy constructor ? When the following four scenarios occur:

1. when a class contains a member object, and the object has a copy constructor in its class (either explicitly declared or implicitly synthesized). at this point, the copy constructor of the member object needs to be called in the synthesized copy constructor.

2 . The base class in a class has a copy constructor (either explicit or implicit). at this point, you need to call the copy constructor of the base class in the synthesized copy constructor.

3. When a virtual function exists in a class (inherited or self-declared). at this point, you need to setthe point of the Vptr (virtual function table pointer) in the synthesized copy constructor.

4. When there is a virtual base class in the inheritance chain of a class (either directly or indirectly). at this point, you need to maintain the location information for the virtual base class part in the synthesized copy constructor.

the situation above and the default constructor can be analogous, to prove that you can also imitate the default constructor call when the way to prove that I was secretly lazy (. ? _ ? . )

It is important to note that by default the copy operation is shallow copy (when there is a pointer, only the value of the pointer is copied, and the object pointed to by the pointer is not copied), in order to implement a deep copy (both the value of the pointer and the object to which the pointer is copied), We need to do it in person.


Second, assignment operator

To allow the assignment operator (=) to perform the operation we specified efficiently, sometimes we need to display the overloaded equals operator. Of course, when a synthetic assignment operator can meet the requirements, there is no need to define it manually, as this may also reduce the execution efficiency. So when do I need to display the overloaded operator ? When a member assignment is not sufficient for our needs, a typical case is when a pointer member is in the class.

We say that when the class does not have its own assignment operator defined, the compiler will synthesize one. This is theoretical (a lot of things are theoretically, as we all know), and the compiler does not necessarily synthesize the corresponding operator functions.

So when does the compiler synthesize it? There are four main cases (the compiler will always synthesize the corresponding function only when it is needed):

1. There is a member object in the class, and there is an assignment operator function in the class of the object. at this point, we need to call this operator when assigning a value to the member object.

2. There is an assignment operator in the base class of the class. at this point, we call this operator when assigning a value to a base class object as part of a derived class object.

3. A virtual function is declared in a class. the value of the right-side vptr (virtual function pointer) cannot be copied directly because it may be a derived class object.

4. This class inherits the virtual base class. the location of the object's virtual base class section may change if you assign a value from a derived class object.

It is easy to prove that:

When only the following simple class definitions

Class A

{

int A;

};

Do the following:

{

A A1;

A A2;

a2 = A1;

}

Its disassembly code such as:


Thus, there is no call to the assignment operator function.

If you add a virtual function to the class above (which is not documented in any other case), the same code is called, and its disassembly is as follows:


There is a default constructor and assignment operator that is visible where the composition is called.

The above four cases can be compared to copy constructor synthesis, in fact, the assignment operator work and copy constructors are similar, but the timing of the call is different. In fact, we should consider these two operations as a unit. If one is needed, we almost certainly need another.

the assignment operator must be defined as a member function and not as a friend function. This is a limitation of grammatical rules, although without this restriction should not be defined as a friend, after all, the call may not be adapted to the person. For example: operator= (A1,A2) corresponds to a1 = A2 this way, is not seem a bit awkward.

When you define yourself, there is a situation that requires special attention: self-assignment, especially when resources need to be released.

The correct way to define this is as follows:

class& class::operator= (const Class &RHS)

{

if (this = = &RHS)

return *this;

   // releasing resources held by an object

   // assign a new resource specified

......

return *this;

}

If you do not judge the circumstances of their own assignment, the direct release of the original resources must be an accident, I think this will not have to say more.


Third, the destructor function

As a complement to the constructor, the destructor opens and allocates the required resources in the constructor, shutting down and releasing the existing resources in the destructor.

The destructor has no return value and no formal parameter , as if it were preceded by a ' ~ ' symbol in front of the default constructor. As follows:

Class a{

......

~a () {cout<< " in destructor" <<endl;} Simple destructor

};

Destructors are called automatically when an object is revoked, and if it is a dynamically allocated object, it is revoked only if a pointer to that object is deleted. Note: Destructors are not run when the object's reference or pointer (whether it is a stack pointer or a pointer to the first address of the new operation) is out of scope. A destructor is run only if you delete a pointer to a dynamically allocated object or an actual object (not a reference or pointer to an object) that is out of scope.

The sample code is as follows:

1. Stack pointer situation:

{

A;

{

A*PA = &a;

}// when Pa goes out of scope, but does not run A's destructor

}// When instance object a is out of scope, the corresponding destructor is run

2. Receive the first address of the new operator:

{

A*pa = new A ();

//delete PA; The call to delete is shown here The statement can be used to deconstruct the object that the PA points to

}// The pa pointer goes out of scope but does not call the destructor, and misses the opportunity to release memory, which causes a memory leak.

3. Case of reference:

{

Aa;

{

A&pa = A;

}// The reference PA at this time is out of scope but does not call the destructor

}// The destructor is called when object a itself is out of scope

Destructors for class-type elements in a container are also run when a container is revoked (whether it is a standard or built-in array).

The sample code is as follows:

{

Aarraya[3] = {A (1), A (2), A (3)};

Vector<a> VA (Arraya,arraya + 3);

A *pa = new A[3];

Delete [] pa;//a destructor that calls 3 elements in PA

}// calling destructors for elements in Arraya and VA

if our class does not display a defined destructor, the compiler will synthesize one for us when needed. the composition destructor revokes each non-static member in reverse order when the object is created, that is, the member is revoked in the reverse sequence of the member's declaration in the class. For a member of a class type, the composition destructor invokes the member's destructor to undo the object. Note: The composition destructor does not delete the object that the pointer member points to.

It says that the compiler will synthesize destructors when needed, so when is the so-called "need"? Is the following two cases:

1.class a member object within the owning destructor (whether synthetic or display defined).

2.class the base class contains destructors (either synthetic or display-defined).

Why do you need a composition destructor at this time? Because the compiler needs to call the corresponding destructor in the composition's destructor to achieve the purpose of the destructor.

For example, the following class definition:

Classvirtualbase

{

int vb;

};

Classa:public Virtual Virtualbase

{

Public

int A;

virtual void Vfun () {}

};

When we have the following code:

{

A;

}

Its disassembly code is as follows:


Although there are virtual functions, virtual inheritance of this complex mechanism, but at this time the compiler still does not synthesize destructors for us. Because in destructors, virtual functions and virtual inheritance bring only two pointers (which can refer to the first ), and the undo pointer does not require additional action (invoking a destructor at this point is an efficiency burden). It is also possible to see that the compiler has synthesized the constructor for us at this time (refer to the fourth type ).

If you have the following class definitions:

Class B

{

String name;

};

A similar code:

{

b b;

}

In this case the disassembly is as follows:


We can see that the corresponding destructor is called later. Because a destructor is defined in the string class, the compiler needs to synthesize a destructor to invoke the destructor of the string class member object.

Here is the sequence of operations for destructors :

1. function body for execution of destructors

2. If the class has member objects and the latter has destructors, they are called in the reverse order of their declaration order.

3. If the object contains a virtual function pointer, it is now reset to point to the virtual function table of the appropriate base class.

4. If there are any direct non-virtual base classes, the latter have destructors, which are called in the reverse order of their declaration order.

5. If any of the virtual base classes have destructors, and the current class is the end-of-class (the last non-virtual base class), then their destructors are called in the reverse order of their original construction order.

As for the order above, as long as you define an appropriate inheritance chain, you can draw a conclusion by displaying the appropriate information for defining the destructor output.

Finally, there is a practical rule of thumb. Three rules: If a class requires a destructor, it also needs to copy the constructor and assignment operators.




C + + Lone Nine sword five--Life Geometry (object copy control)

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.