[C + + reference] The parameter of the copy constructor must be a reference type

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. This is said in effective C + +: The parameters of the copy constructor must be of reference type . But why?

The parameter of the copy constructor must be a reference type

If the parameter in the copy constructor is not a reference, that is, like Cclass (const cclass c_class), it is equivalent to a pass-through value (Pass-by-value), and the method of passing the value calls the copy constructor of the class. This results in infinite recursive invocation of the copy constructor. Therefore, the parameter of the copy constructor must be a reference.

It should be clarified that the pointer is actually a value, if the above copy constructor is written as Cclass (const cclass* c_class), it can be run. But after the parameter is changed, it is not a copy constructor, it has become a normal constructor, and the program will not call it automatically when it needs to copy the constructor.

Look at the following code:

#include <iostream>using namespace Std;class cexample{private:int m_ntest;public:cexample (int x): m_ntest (x)      //With parameter constructor {cout << "constructor with argument" <<endl;} Copy constructor, const in parameter is not strictly required, but reference symbol is required cexample (const Cexample & Ex)     //copy constructor {m_ntest = Ex.m_ntest;cout << "Copy constructor" <<endl;} cexample& operator = (const cexample &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;}

The output of this example:

Constructor with argument        //Cexample aaa (2), constructor with argument        //cexample BBB (3); Assignment operator< c2/>//bbb = aaa;copy constructor                 //Cexample CCC = Aaa;copy constructor                 //  Bbb.mytestfunc (AAA);

Analysis: There is nothing special about the first and the second, which is the normal constructor. The third and fourth why the results are different:

The reason is that the BBB object has already been instantiated and does not need to be constructed, at this point only the AAA is assigned to BBB, only the assignment function is called. However, the CCC is not instantiated, so it calls the copy constructor, constructs the CCC, and not the assignment function.

Fifth: The AAA is actually passed as a parameter to Bbb.mytestfunc (Cexample ex), i.e. cexample ex = AAA, and fourth consistent, so copy the constructor instead of the assignment function.

In this example, let's analyze why the parameters of a copy constructor can only use reference types.

See Fourth output: Copy constructor//cexample CCC = AAA;

The construction of CCC is essentially the CCC. Cexample (AAA); If the copy constructor parameter is not a reference type, then the CCC will be made. Cexample (AAA) becomes AAA to pass value to CCC. Cexample (Cexample ex), i.e. cexample ex = AAA, since ex is not initialized, cexample ex = AAA continues to call the copy constructor, followed by the construction ex, which is ex. Cexample (AAA), will inevitably have AAA passed to Cexample (Cexample ex), that is, cexample ex = AAA, then trigger the copy constructor, the next forever recursion down.

In C + +, there are three scenarios for invoking a copy constructor:

1. An object is passed into the function body as a function parameter, in the way of value passing .

2. An object is returned from the function as a function return value, in the way that the value is passed .

3. An object is used to initialize another object ( initialized when the object is created).

If the constructor is not explicitly declared, the compiler will synthesize a default constructor for a class. If a constructor is declared in a class, it prevents the compiler from compositing the default constructor for that class. But other constructors are defined (but no copy constructors are defined), and the compiler always synthesizes a copy constructor for us, meaning that the custom constructor does not block the default copy constructor.

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

#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;     The copy constructor}int main (void) {A test;fun (test) is called when the return is not a reference, system ("pause"); return 0;}

  

When to customize copy constructors and assignment functions.

Simple rule: If you need to define a non-empty destructor, you typically also need to define a copy constructor and an assignment function.

The general principle is:

1. A copy constructor should be provided for any class that contains dynamically allocated members or contains pointer members;

2. While providing a copy constructor, you should also consider overloading the "=" assignment operator, which provides the assignment function.

When we know that we need to customize copy constructors and assignment functions, we have to consider how to implement them well.

When customizing copying functions (including copy constructors and assignment functions), you need to ensure the following two points:

1. Copy all the local member variables

2. Call the appropriate copying function within all base classes to complete the copying of the base class.

Here is a specific example:

Class Customer {public: ...    Customer (const customer& RHS);    customer& operator= (const customer& RHS); ... private:std::string name;}; Customer::customer (const customer& RHS): Name (rhs.name) {cout << "Customer copy constructor" << Endl;} customer& customer::operator= (const customer& RHS) {cout << "Customer copy assignment Operator" <<    Endl                    name = Rhs.name;    Wondering why private variables can be called through objects in the copying function? return *this;}    Class Prioritycustomer:public Customer {public: ...    Prioritycustomer (const prioritycustomer& RHS);    prioritycustomer& operator= (const prioritycustomer& RHS); ... private:int priority;}; Prioritycustomer::P rioritycustomer (const prioritycustomer& RHS): Customer (RHS), priority (Rhs.priority) {cout << "Prioritycustomer copy constructor" << Endl;} prioritycustomer& prioritycustomer::operator= (const prioritycustomer& RHS) {cout << PrioritycustoMer copy assignment operator "<< Endl;                Customer::operator= (RHS);    Assignment of the base class component to Priority = Rhs.priority; return *this;}

The above code, direct access to private member variables through the object, seems to violate the object's encapsulation, specific analysis and understanding refer to the following link:

Understanding of C + + Private member variables

[C + + reference] The parameter of the copy constructor must be a reference type

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.