The parameter type of a copy constructor in C + + must be a reference to the _c language

Source: Internet
Author: User

In C + +, constructors, copy constructors, destructors and assignment functions (assignment operator overloading) are the most basic knowledge that needs to be mastered. But if I ask you, "Why do the parameters of a copy constructor have to use a reference type?" "The question, how would you answer?" Perhaps you would answer in order to reduce the memory copy at a time? I am ashamed to say that my first feeling is the same. But fortunately, I think about later, found that the answer is wrong.

Reason:
If the parameter in the copy constructor is not a reference, that is, a form like Cclass (const cclass c_class), it is equivalent to the way in which the value is passed (Pass-by-value), and the method of passing the value calls the copy constructor of the class. Thus causing infinite recursion to invoke the copy constructor. Therefore, the parameters of the copy constructor must be a reference.

What needs to be clarified is that the pass pointer is actually a value, and if the copy constructor above is written as Cclass (const cclass* c_class), it will not work. In fact, all other passes are values, except that the pass-through reference is not a passing value.
Start with a small example: Test yourself to see what the output of this program is? )

Copy Code code as follows:

#include <iostream>
using namespace Std;
Class Cexample
{
Private
int m_ntest;
Public
Cexample (int x): m_ntest (x)//with parameter constructors
{
cout << "constructor with argument" <<endl;
}
Copy constructors, const in parameters are not strictly required, but reference symbols are required
Cexample (const Cexample & Ex)//copy constructor
{
M_ntest = Ex.m_ntest;
cout << "copy constructor" <<endl;
}
cexample& operator = (const cexample &AMP;EX)//Assignment function (Assignment operator overload)
{
cout << "assignment operator" <<endl;
M_ntest = Ex.m_ntest;
return *this;
}
void Mytestfunc (Cexample ex)
{
}
};
int main (void)
{
Cexample aaa (2);
Cexample BBB (3);
BBB = AAA;
Cexample CCC = AAA;
Bbb.mytestfunc (AAA);
return 0;
}

If you can see that is the result, congratulations, you can stand up and twist your butt, no need to look down.
If your results and output errors, then please be humble to read.
First output: constructor with argument//Cexample aaa (2);
If you do not understand, find someone to drag you out to beat a meal, and then the mouth also shouted "I am the second brother, I was two seniors ..."
Second output: constructor with argument//Cexample BBB (3);
Analysis with the first
Third output: assignment operator//bbb = AAA;
Fourth output: copy constructor//cexample CCC = AAA;
these two have to be put together to say. There will certainly be people asking why two inconsistencies. The reason is that the BBB object has been instantiated, do not need to construct, at this time just the value of AAA assigned to BBB, will only call the assignment function, it is so simple, do not understand the words, wall to go! But CCC has not been instantiated, so the call is a copy of the constructor, the construction of the CCC, rather than the assignment function, still do not understand the words, I wall go!!
Fifth output: Copy constructor//Bbb.mytestfunc (AAA);
is actually AAA passed as a parameter to Bbb.mytestfunc (Cexample ex), that is, cexample ex = AAA; and fourth consistent, so or copy constructors, not assignment functions, if you still don't understand, my head is bleeding, don't let me hit again, You just try to reload it yourself.
With this example, let's analyze why the parameters of a copy constructor can only use reference types.
Look at the fourth output: copy constructor//cexample CCC = AAA;
Construction of CCC, is essentially CCC. Cexample (AAA); If the copy constructor parameter is not a reference type, then the CCC will be made. Cexample (AAA) becomes AAA and passes the value to CCC. Cexample (Cexample ex), that is, cexample ex = AAA, since ex was not initialized, cexample ex = AAA continues to invoke the copy constructor, followed by the construction ex, which is ex. Cexample (AAA) is bound to have AAA passed to Cexample (Cexample ex), that is, cexample ex = AAA; then it triggers the copy constructor, which is forever recursive.
So the Big Bend is to show that the parameters of the copy constructor use the reference type not to reduce the memory copy at a time, but to prevent the copy constructor from being recursive indefinitely.

With the instructions, the copy constructor is invoked in the following situations:
A, explicitly or implicitly, initializes another object with an object of the same type. As in the example above, initialize D with object C;
B, passed as an argument (argument) to a function. As in Cclass (const cclass c_class), the Cclass copy constructor is invoked;
C, the copy constructor of the return value type is also invoked when an object is returned in the function body;
D, initializing the elements in the sequence container. For example, Vector<string> Svec (5), the default constructor and copy constructor for string are invoked;
E, when initializing an array element in a list format. String a[] = {string ("Hello"), String ("World")}; A copy constructor of string is called.

If you do not explicitly declare a constructor, the compiler will synthesize a default constructor for a class. If a constructor is declared in a class, the compiler is prevented from synthesizing the default constructor for that class. Unlike constructors, the compiler will always synthesize a copy constructor for us, even if other constructors are defined (but no copy constructors are defined).

In addition, the return value of the function is not a reference also has a very big difference, the return is not a reference, just a simple object, at this time need to call the copy constructor, otherwise, if the reference is not required to call the copy constructor.

Copy Code code as follows:

#include <iostream>
using namespace Std;
Class A
{
Private
int m_ntest;
Public
A ()
{
}
A (const a& Other)//constructor overload
{
M_ntest = Other.m_ntest;
cout << "copy constructor" <<endl;
}
A & operator = (const a& Other)
{
if (this!= &other)
{
M_ntest = Other.m_ntest;
cout<< "Copy Assign" <<endl;
}
return *this;
}
};
A fun (a &x)
{
return x; When the return is not a reference, you need to call the copy constructor
}
int main (void)
{
A test;
Fun (test);
System ("pause");
return 0;
}

Share a written question, compile and run the C + + code in the following figure, what is the result? (A) compilation error, (B) successful compilation, run-time program crashes, (C) compile run normally, output 10. Please select the correct answer and analyze the reason.
Copy Code code as follows:

Class A
{
Private
int value;
Public
A (int n)
{
Value = N;
}
A (a)
{
value = Other.value;
}
void Print ()
{
cout<<value<<endl;
}
};
int main (void)
{
A A = 10;
A b = A;
B.print ();
return 0;
}

Answer: compilation error. The parameter passed in the copy constructor is an instance of a. Because it is a value, copy the formal parameter to the actual participant call the copy constructor. Therefore, if a copy constructor is allowed to pass a value, a never-ending recursive merge is created to cause a stack overflow. Therefore, the standard of C + + does not allow replication of constructor pass-value parameters, but must be a reference or a constant reference. In Visual Studio and GCC, errors are compiled.

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.