Copy constructor of C ++ class objects

Source: Internet
Author: User

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 iostream
using namespace STD;
class test
{< br> Public :
test ( int temp)
{< br> P1 = temp;
}< br> protected :
int P1;

};
void main ()
{< br> Test A (99);
Test B = A;
}

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 performs different operations on them. For Class objects, class objects of the same type areCopy constructorTo complete the entire replication process.CodeIn, we didn't see the copy constructor, And the replication work was also completed. Why? Because when a class does not have a custom copy constructor, the system automatically providesDefault copy constructorTo complete the replication.

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 < Iostream >
Using Namespace STD;

Class Test
{
Public :
Test ( Int Temp)
{
P1 = temp;
}
Test (test & c_t) // Here is the custom copy constructor.
{
Cout <"Enter the copy constructor" <Endl;
P1 = c_t.p1;// If this statement is removed, the copy cannot be completed. The core statement of this statement is used in the copy process.
}
Public :
Int P1;
};

Void Main ()
{
Test A (99 );
Test B =;
Cout <B. P1;
CIN . Get ();
}

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, function Form parameters are reference variables of this type,AndRequiredYes reference.

When an initialized custom class object is used to initialize another newly constructed object, the copy constructor will beAutomatic CallIf 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 copy the P1 = c_t.p1 In the constructor through test (test & c_t. 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. Because of the replication process, object B obtains the heap address opened by object A. OnceProgramProduction analysis structure. When the heap is released, it is impossible for the 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 < Iostream >
Using Namespace STD;

Class Internet
{
Public :
Internet ( Char * Name, Char * Address)
{
Cout <"Load constructor" <Endl;
Strcpy (Internet: Name, name );
Strcpy (Internet: Address, address );
Cname = New Char [Strlen (name) + 1];
If (Cname! = NULL)
{
Strcpy (Internet: cname, name );
}
}
Internet (Internet & temp)
{
Cout <"Load copy constructor" <Endl;
Strcpy (Internet: name, temp. Name );
Strcpy (Internet: Address, temp. Address );
Cname = New Char [Strlen (name) + 1]; // Pay attention to the embodiment of deep copy!
If (Cname! = NULL)
{
Strcpy (Internet: cname, name );
}
}
~ Internet ()
{
Cout <"Load destructor! ";
Delete [] Cname;
CIN . Get ();
}
Void Show ();
Protected :
Char Name [20];
Char Address [30];
Char * Cname;
};
Void Internet: Show ()
{
Cout <Name <":" <address <cname <Endl;
}
Void Test (Internet TS)
{
Cout <"Load test function" <Endl;
}
Void Main ()
{
Internet A ("China Software Development Lab", "www.cndev-lab.com ");
Internet B = A;
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 copy and shortest can be simply understood:If a class has resources (heap, or other system resources), when the object of this class is copied, this process can be calledDeep copyIf the object has resources but the resources are not copied during the replication processShortest 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.ReturnsCustom typeObjectFollow this rule?Generate temporary object!

Run the following code first:

# Include < Iostream >
Using Namespace STD;

Class Internet
{
Public :
Internet ()
{

};
Internet ( Char * Name, Char * Address)
{
Cout <"Load constructor" <Endl;
Strcpy (Internet: Name, name );
}
Internet (Internet & temp)
{
Cout <"Load copy constructor" <Endl;
Strcpy (Internet: name, temp. Name );
CIN . Get ();
}
~ Internet ()
{
Cout <"Load destructor! ";
CIN . Get ();
}
Protected :
Char Name [20];
Char Address [20];
};
Internet TP ()
{
Internet B ("China Software Development Lab", "www.cndev-lab.com ");
Return B;
}
Void Main ()
{
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.

Let's take a look at the content of this section.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 < Iostream >
Using Namespace STD;

Class Internet
{
Public :
Internet ( Char * Name, Char * Address)
{
Cout <"Load constructor" <Endl;
Strcpy (Internet: Name, name );
}
Internet (Internet & temp)
{
Cout <"Load copy constructor" <Endl;
Strcpy (Internet: name, temp. Name );
CIN . Get ();
}
~ Internet ()
{
Cout <"Load destructor! ";
}
Public :
Char Name [20];
Char Address [20];
};

Void Main ()
{
Internet A = Internet ("China Software Development Lab", "www.cndev-lab.com ");
Cout <A. Name;
CIN . Get ();
}

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 < Iostream >
Using Namespace STD;

Class Internet
{
Public :
Internet ( Char * Name, Char * Address)
{
Cout <"Load constructor" <Endl;
Strcpy (Internet: Name, name );
}
Internet (Internet & temp)
{
Cout <"Load copy constructor" <Endl;
Strcpy (Internet: name, temp. Name );
CIN . Get ();
}
~ Internet ()
{
Cout <"Load destructor! ";
}
Public :
Char Name [20];
Char Address [20];
};

Void Main ()
{
Internet & A = Internet ("China Software Development Lab", "www.cndev-lab.com ");
Cout <A. Name;
CIN . Get ();
}

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 ");

, Observe the position of calling the Destructor (This situation is called outside main (), while the nameless object is parsed in main ().).

Related Article

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.