Copy object--oeprator= with copy constructor correctly

Source: Internet
Author: User

Well, that's a weird name, =_=.

OK, the following into the topic, in order to demonstrate convenience, the code only write a brief section.

copy Constructor
class Base{public:    Base() {}    Base(const Base& )     {        cout<<"Base copy "<<endl;    }};classDerivedpublic Base{public:    Derived() {}    Derived(constDerived& ind) {}};

Focus on the copy constructor.
Although there is no data in the class-but we said, to demonstrate convenience-now assume that the base class has correctly written its own variable copy.
When you have the following code:

    Derived d;    Derived s(d);

We want it to behave as if it would output

Base Copy

Of course, when the derived class copy construct occurs, we also want the copy construct of its base class to run correctly.

Then the real behavior is that there is no output.
Because, when we have to write a copy constructor for the derived class, we must carefully copy the elements of the base class [1].

The correct writing should be:

public Base{public:    Derived() {}    Derived(const//在这里调用base class 的构造函数};

Another class member function associated with replication is operator=.

operator= operator

In the above, it has been pointed out that when we have to write the copy constructor ourselves, we should carefully copy the object.
The same is true when you write the operator= operator, and the code is given directly below:

Class base{ Public:Base() {} Base (Constbase&) {cout<<"Base copy"<<endl; } base&operator= (Constbase&)//Make operator = return a reference to itself is a good practice    //Why? Check the information yourself:){cout<<"Base ="<<endl;return* This; }};class Derived: Publicbase{ Public:Derived() {} Derived (Constderived& Ind): Base (Ind) {} derived&operator= (Constderived& Ind) {Base::operator= (IND);//!! This can't be missed!!         return* This; }};

* The output in the class is just to better see the behavior of the class, only for demonstration purposes, and it doesn't really make sense.

Do you see the red Note, please don't miss out.

Perhaps you have doubts, it will not be written every time for derived class, you have to write the copy constructor and operator = operator, even if the compiler provides a default version is sufficient to meet our needs?
Don't worry, the compiler will handle it correctly, so you can try it yourself:)

However, the case of operator = is a bit more complicated, pay attention to handling self-assignment in operator =.
Now let's take a single class as an example and give it a pointer to a resource. Well............ It's almost like this:

struct  t{int  i;}; class     base{t* p; Base (const  base&); public : Base () {p = new  t{3 };    } ~base () {delete  p;        } base& operator  = (const  base& inb) {        delete  p;        p = new  T (*INB.P);    return  *this ; } void  print () //this function is to verify the result  {cout  <<p->i<<endl; }};

OK, now there's code that uses them:

    Base b1;    Base b2;    b2 = b1;    b2 = b2;//注意这句    b2.print

Although the class of writing doesn't make sense, we expect it to output 3 if we look at it in single use.
But the real behavior is: 0.
The reason is that the self-assignment is not handled correctly in operator =.
When there is b2 = b2 such a statement (see note below)

    operator = (const Base& inb)    {        delete p;                    //此时inb == *this, delete p 的时候,其实也删除了自身的资源        //那么后面的行为就是不确定的了        new T(*inb.p);        return *this;    }

Oddly, the operation was not an error, the program as always, cheerfully run, although unpredictable behavior.

Then deal with this problem by adding self-certification to the test:

    operator = (const Base& inb)    {        if(this == &inb)    return *this//自我证同测试        delete p;        new T(*inb.p);        return *this;    }

So what's the price?
A control branch was introduced.
The question is, how much will the probability of self-assignment occur?
If you have to make a judgment every time, it will inevitably affect the efficiency.

So the wise man thought of the second approach:copy and swap technology

    operator = (const Base& inb)    {        new T(*inb.p);        delete p;        p = temp;        return *this;    }

A copy is constructed first, and then the pointer value is exchanged.
Even self-assignment does not affect the correct behavior.
If you are concerned, when self-assignment, first construct a copy of their own, and then give back to yourself, will not superfluous?
You think about the probability of self-assignment, and then consider whether it's worth it:)

[References]
[1] Scott Meyers, Houtie. Effective C + +: 55 Effective practices for improving program technology and design thinking [M]. Electronic industry Press, 2011.
(clause 11: Handling "self-assignment" in operator=;
Article 12: Do not forget every ingredient when copying an object

Copy object--oeprator= with copy constructor correctly

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.