C ++ Class Object's deep copy and shallow copy constructor

Source: Internet
Author: User
C ++ Class Object's deep copy and shortest copy constructor-Linux general technology-Linux programming and kernel information. The following is a detailed description. Before learning this chapter, we have learned about class constructor and destructor. For common type objects, copying between them is very simple, for example:

Int a = 10;
Int B =;

The objects of the defined classes are also objects. No one can prevent us from copying them in the following ways, for example:

# Include
Usingnamespacestd;

ClassTest
{
Public:
Test (inttemp)
{
P1 = temp;
}
Protected:
Intp1;

};

Voidmain ()
{
Test a (99 );
Test B =;
}

Common objects and class objects are the same objects. Their features are similar and different. class objects have member variables, but common objects do not, when the same replication method occurs on different objects, the system also performs different operations on them. For Class objects, class objects of the same type are copied through the copy constructor to complete the entire replication process. In the above Code, we did not see the copy constructor, and we also completed the replication, why? Because when a class does not have a custom copy constructor, the system automatically provides a default copy constructor to complete the copy.

Next, we define a copy constructor that is the same as the default copy constructor of the system to illustrate the situation (for example, the above Code, let's see how it works internally!

The Code is as follows:

# Include
Usingnamespacestd;

ClassTest
{
Public:
Test (inttemp)
{
P1 = temp;
}
Test (Test & c_t) // here is the custom copy constructor.
{
Cout <"Enter copy constructor" }
Public:
Intp1;
};

Voidmain ()
{
Test a (99 );
Test B =;
Cout }

Test (Test & c_t) in the code above is our custom copy constructor. The name of the copy constructor must be consistent with the class name, A function form parameter is a reference variable of this type and must be a reference.

When an initialized custom class object is used to initialize another newly constructed object, the copy constructor is automatically called, if you do not have a custom copy constructor, the system will provide a default copy constructor to complete this process. The core statement for copying the code above is to use Test (Test & c_t) copy the p1 = c_t.p1 In the constructor; the statement is complete. If this code is removed, the p1 attribute of object B will obtain an unknown random value;

Next we will discuss the issues of the shortest copy and the deep copy.

As for the above Code, many people will ask, since the system will automatically provide a default copy constructor to process replication, it makes no sense to define a copy constructor, yes, in general cases, this is indeed unnecessary. However, in a write condition, the members of the class body need to dynamically open up heap memory, if we do not customize the copy constructor and let the system process it by ourselves, it will lead to confusion about the ownership of the heap memory, the heap address opened at one end originally belongs to object a. As a result of the replication process, object B obtains the heap address opened by object a. Once the program produces a structure and releases the heap, it is impossible for a computer to know who the address actually belongs to. When two consecutive analyses occur, a running error occurs.

For more details, see the following code.

# Include
Usingnamespacestd;

ClassInternet
{
Public:
Internet (char * name, char * address)
{
Cout <"load constructor" Strcpy (Internet: address, address );
Cname = newchar [strlen (name) + 1];
If (cname! = NULL)
{
Strcpy (Internet: cname, name );
}
}
Internet (Internet & temp)
{
Cout <"load COPY constructor" Strcpy (Internet: address, temp. address );
Cname = newchar [strlen (name) + 1]; // note that this is the embodiment of deep copy!
If (cname! = NULL)
{
Strcpy (Internet: cname, name );
}
}
~ Internet ()
{
Cout <"load destructor! ";
Delete [] cname;
Cin. get ();
}
Voidshow ();
Protected:
Charname [20];
Charaddress [30];
Char * cname;
};
VoidInternet: show ()
{
Cout <}
Voidtest (Internet ts)
{
Cout <"load test function" <}
Voidmain ()
{
Internet a ("China Software Development Lab", "www.cndev-lab.com ");
Internet B =;
B. show ();
Test (B );
}

The code above demonstrates the deep copy problem. The cname attribute of object B adopts the new memory opening method to avoid the error of Memory Attribution leading to space release analysis, at last, I have to mention that I have not explained much about the above programs. I hope that the readers can run the programs themselves to observe the changes and gain a deep understanding.

The definition of deep copy and shallow copy can be simply understood as: If a class has resources (heap, or other system resources), when the object of this class is copied, this process can be called Deep copy. If the object has resources but the copying process does not copy resources, it is considered as a light copy.

A program running error occurs when resources are released after the resources are copied in a shortest environment!

Previously, we discussed in our tutorial the problem of generating temporary variables for function returned objects. Next, let's take a look at whether the returned custom type objects in the function also follow this rule to generate temporary objects!

Run the following code first:

# Include
Usingnamespacestd;

ClassInternet
{
Public:
Internet ()
{

};
Internet (char * name, char * address)
{
Cout <"load constructor" Strcpy (Internet: address, address );
}
Internet (Internet & temp)
{
Cout <"load COPY constructor" Strcpy (Internet: address, temp. address );
Cin. get ();
}
~ Internet ()
{
Cout <"load destructor! ";
Cin. get ();
}
Protected:
Charname [20];
Charaddress [20];
};
Internet tp ()
{
Internet B ("China Software Development Lab", "www.cndev-lab.com ");
Returnb;
}
Voidmain ()
{
Internet;
A = tp ();
}

From the code running result, we can see that the program has loaded the Destructor three times in total, proving that a temporary variable will also be generated when the function returns a custom type object, in fact, object a obtains the temp value of the Temporary Internet class object.

The content in this section is an unknown object.

The object system does not call the copy constructor to initialize an object with an unknown object.

So what is an unknown object?

It is very simple. If the main function of the above program contains:

Internet ("China Software Development Lab", "www.cndev-lab.com ");

Such a statement will generate an unknown object. An unknown object will call the constructor, but the object initialization system will not call the copy constructor!

The following three pieces of code are three examples of initializing objects with unknown objects.

# Include
Usingnamespacestd;

ClassInternet
{
Public:
Internet (char * name, char * address)
{
Cout <"load constructor" }
Internet (Internet & temp)
{
Cout <"load COPY constructor" Cin. get ();
}
~ Internet ()
{
Cout <"load destructor! ";
Cin. get ();
}
Public:
Charname [20];
Charaddress [20];
};

Voidmain ()
{
Internet a = Internet ("China Software Development Lab", "www.cndev-lab.com ");
Cout }

The running result of the above Code is a bit "unexpected". In terms of thinking logic, when an unknown object is created, it is necessary to call the custom copy constructor, or, by default, the copy constructor completes the replication process, but the system does not actually do this, because the Untitled object is useless in the whole program after it is used, in this case, c ++ regards the code:

Internet a ("China Software Development Lab", "www.cndev-lab.com ");

The process of creating an unknown object is omitted, so the copy constructor will not be called.

Finally, let's take a look at the reference of an unknown object.

# Include
Usingnamespacestd;

ClassInternet
{
Public:
Internet (char * name, char * address)
{
Cout <"load constructor" }
Internet (Internet & temp)
{
Cout <"load COPY constructor" Cin. get ();
}
~ Internet ()
{
Cout <"load destructor! ";
}
Public:
Charname [20];
Charaddress [20];
};

Voidmain ()
{
Internet & a = Internet ("China Software Development Lab", "www.cndev-lab.com ");
Cout }

The reference itself is the alias of the object, and it has nothing to do with replication, so it will not call the copy constructor. However, it should be noted that in c ++'s view:

Internet & a = Internet ("China Software Development Lab", "www.cndev-lab.com ");

Is equivalent:

Internet a ("China Software Development Lab", "www.cndev-lab.com ");

, Pay attention to observe the position of calling the Destructor (this situation is called outside main (), while the unknown object itself is parsed within main ).

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.