Perhaps many beginners in C + + know what a constructor is, but they are unfamiliar with the copy constructor (copy constructor). For me, there's not much chance of using a copy constructor when writing code, but that doesn't mean that the copy constructor is useless, but the copy constructor solves some of the problems that we often ignore. to illustrate the role of the copy constructor, let me start by talking about some of the problems we're going to have in programming. For the functions in C + +, we should be very familiar with, because it is often used, for the object of the class, we are also familiar with, because we often write a variety of classes, using a variety of objects, we are not unfamiliar with the operation of the pointer. Well, if you don't know the above three concepts, I don't think this article is very suitable for you, but it's not ^_^. We often use functions to pass a variety of arguments to a function, but we should compare objects (note the object, not the object's pointer or object reference) as a parameter to the function of the case we should less meet, and the constructor of this object also involves some memory allocation operations. Well, what's wrong with that? There are three ways to pass parameters to a function, one is value transfer, one is the address, and one is the reference. The difference between the former and the latter is that when the value is passed, a copy of the pass parameter is generated in the function, and the contents of the copy are copied from the original parameter, the contents of which are the same. When the original argument is an object of a class, it also produces a copy of the object, but notice here. When a generic object is generated, it triggers the execution of the constructor, but not when the copy of the object is generated, when the copy constructor of the object is executed. Why is this. Well, general constructors do work with some member property initialization, before an object is passed to a function, some properties of the object may have been changed, and if the object's constructor is executed when the object's copy is generated, then the object's properties are restored to its original state, which is not what we want. So when a copy of the object is generated, the constructor is not executed and a default constructor is executed. When the function completes to return, the object copy executes the destructor, and if your destructor is empty, nothing will happen, but the general destructor is to do some cleanup work, such as releasing the memory space that the pointer points to. That's when the problem may be coming up. If you assign memory to a pointer variable in the constructor, releasing the memory space assigned to the pointer in the destructor, what happens when the object is passed to the function to return to the function end. First, a copy of the object is generated,This copy also has a pointer to the same block of memory space as the original object's pointer. When the function returns, the destructor of the object is executed, which frees the memory space pointed to by the pointer in the object's copy, but this memory space is useful to the original object, which is a serious error in the program itself. However, the error is not yet over, when the original object is also destroyed, the destructor executed again, the same block system dynamically allocated memory space two times is an unknown operation, will produce serious errors. Above is the problem that we will encounter. What is the way to solve the problem? The first thing we think of is not to pass the parameter in the way of value, we can use the address or the reference. Yes, it does avoid the above, and it's best to pass the address or reference when allowed, but it doesn't work for all situations, and sometimes we don't want some of the operations inside the function to affect variables outside the function. Well, what do we do? You can use a copy constructor to resolve this problem. The copy constructor executes when a copy of the object is generated, and we can define our own copy constructor. In the copy constructor we apply for a new memory space to hold the content that the pointer in the constructor points to. This frees up the memory space that is requested in the copy constructor when the destructor of the object copy is executed. In addition to passing objects to a function, there are problems, there is also a situation where the problem is that when the function returned to the object, it will produce a temporary object, this temporary object and the object of the nature of the copy. A copy constructor, often called X (x&), is a special constructor that is called by the compiler to perform artifacts and initializations based on other objects of the same class. Its unique parameter (a reference to an object) is immutable (because it is a const type). This function is often used to pass and return the value of a user-defined type during a function call. Copy constructors call the copy constructors and member functions of the base class. If it can, it will be called in a constant way, or it can be called in a very different way. in C + +, the following three types of objects need to be copied. Therefore, the copy constructor will be invoked. 1). An object is passed in as a value in the function Body 2). An object returns 3 from the function in a value-passing manner. An object needs to be initialized with another object above requires the invocation of a copy constructor. If the copy constructor is not used in the first two cases, it causes a pointer to point to the memory space that has been deleted. For the third case, the different meaning of initialization and assignment is the constructor callThe reason. In fact, copy constructors are implemented by common constructors and assignment operations. There are a number of reference materials that describe the similarities and differences between copy constructors and assignment operators. The copy constructor cannot change the object it refers to, for the following reasons: When an object transmits a function in the form of a value, the copy constructor is automatically invoked to generate the object in the function. If an object is passed into its own copy constructor, its copy constructor will be called to copy the object so that replication can pass into its own copy constructor, which can result in an infinite loop. In addition to being implicitly invoked when an object passes in a function, the copy constructor is also invoked when the object is returned by the function. In other words, what you get back from the function is just a copy of the object. But again, the copy constructor is called correctly, and you don't have to worry about it. If there is no explicit declaration of a copy constructor in the class, the compiler will secretly create a function for you to perform a bit copy between the objects (bitwise copy). This implied copy constructor simply associates all of the class members. Many authors will mention this default copy constructor. Note that the difference between this implicit copy constructor and the explicitly declared copy constructor is the way that the member is associated. An explicitly declared copy constructor associates only the default constructor of a class member that is instantiated unless another constructor is invoked when the class is initialized or when the list is constructed. The copy constructor is a more efficient program because it changes the constructor's argument list without having to construct an object again. Designing a copy constructor is a good style, even if the compiled system provides help for you to request a memory default copy constructor. In fact, the default copy constructor can handle many situations. With another article on the copy constructor: The initialization method for a simple variable is to initialize another variable with a constant or variable, for example: int m =; int n = m; we've already initialized the object with the constructor, so can we just as initialize the simple variable object to initialize another object. The answer is yes. We take the point class defined above as an example: Point pt1 (15, 25); Point pt2 = pt1; The latter statement can also be written as: Point Pt2 (PT1); It initializes the pt2 with Pt1, at which point the values of PT2 members are the same as those of PT1 members, that is, the values of pt1 individual members are copied to the corresponding members of the PT2. In this initialization process, a copy constructor is actually called. When we do not explicitly define a copy constructor, the compiler implicitly defines a default copy constructor.It is an inline, publicly-owned member that has the following prototype form: Point: Point (Const-point &); As you can see, the difference between a copy constructor and a constructor is a formal parameter, which is a reference to a point object, and its function is to copy each member of one object to the corresponding member of another object. Although not necessary, we can explicitly define a copy constructor for the point class: Point:: Point (Const-point &pt) {xval=pt. xval; Yval=pt. Yval; } If you have a pointer member in a class, the problem occurs when you initialize the object with the default copy constructor. To illustrate the problem, we assume that object A is the same class as Object B, has a pointer member, and points to object C. When object A is initialized with object B, the default copy constructor copies the value of each member in B to the corresponding member of a, but does not copy object C. That is, the pointer members in object A and object B point to Object C, and in fact, we want object C to be copied as well, to get the object copy D of C. Otherwise, when objects A and B are destroyed, the memory area of Object C is repeatedly released, causing an error. In order for object C to also be replicated, you must explicitly define the copy constructor. Let's take the string class as an example to illustrate how to define this copy constructor.
Example 10-11 class String {public:string ();//constructor string (const string &s);//copy constructor ~string ();//destructor/interface function void set (char const *data); char const *get (void);
Private:char *str; The data member PTR points to the assigned string};
String:: String (const string &s) {str = new Char[strlen (S.STR) + 1]; strcpy (str, S.STR); }
We also use nameless objects to initialize another object, for example: Point pt = Point (10, 20); The class name calls the constructor directly and generates an unnamed object that initializes the right PT object with the unnamed object on the left. The constructor is invoked usually in the following three cases, the first is what we see above: When you initialize another object with one object, the second is when the object is a function argument, the argument is passed to the formal parameter, and the third occurs when the other temporary object is created during the program's execution. Let's take another example to illustrate the second and third scenarios: Point foo (Point pt) {... return pt; } void Main () {Point pt1 = Point (10, 20); Point Pt2; ... Pt2=foo (PT); ... } When the Foo function is called in the main function, the argument PT is passed to the formal parameter pt, and the argument pt is copied to the formal parameter pt, to invoke the copy constructor, and when the function foo returns, a temporary object of PT is created, and the copy constructor is called at this time.
Default copy constructors in the definition of a class, if the copy constructor is not explicitly defined, the C + + compiler automatically defines a default copy constructor. The following is an example of using a copy constructor:
Example 10-12 #include <iostream.h> #include <string.h> class WITHCC {PUBLIC:WITHCC () {} WITHCC (const WITHCC&AM P;) {cout<< "WITHCC (withcc&)" <<endl; } }; Class Wocc {enum{bsz = 100}; Char Buf[bsz]; PUBLIC:WOCC (const char* msg = 0) {memset (buf, 0, Bsz); if (msg) strncpy (buf, MSG, BSZ); } void Print (const char* MSG = 0) const {if (msg) cout<<msg<< ":"; cout<<buf<<endl; } };
Class Composite {WITHCC WITHCC; WOCC WOCC; Public:composite (): Wocc ("composite ()") {} void print (const char* msg = 0) {wocc.print (msg); } };
void Main () {composite C; C.print ("contents of C"); cout<< "Calling composite Copy-constructor" <<endl; Composite C2 = C; C2.print ("contents of C2"); }
Class WITHCC has a copy constructor, both class Wocc and class composite do not explicitly define a copy constructor. If the copy constructor is not explicitly defined in the class, the compiler automatically creates a default constructor. In this case, however, this constructor does nothing. The class composite contains both the member object of the WITHCC class and the member object of the Wocc class, which uses the parameterless constructor to create the object WITHCC of the WITHCC class (note the initialization method of the embedded object WOCC). In the main () function, the statement: composite C2 = C; By initializing object C2 with Object C, the default copy constructor is invoked. The best way to do this is to create your own copy constructor without expecting the compiler to create it so that the program is under our own control.
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.