C ++ core principles C.62: to ensure the safety copy assignment to assignment to self

C. 62: Copy the Assignment the Make Self-Safe for the Assignment
c. 62: copy assignment to ensure the safety of self-evaluation

 

 

 

Reason (reason)

If x = x changes the value of x, people will be surprised and bad errors will occur (often including leaks).

If x = x changed the value of x, people will find it very strange, but very bad error will occur. (Usually contain leak)

 

 

Example (Example)

The standard-library containers handle self-assignment elegantly and efficiently:

Standard Library container handling self assignment elegant and efficient way:

 

std::vector<int> v = {3, 1, 4, 1, 5, 9};
v = v;
// the value of v is still {3, 1, 4, 1, 5, 9}

 

 

 

Note (Note)

The default assignment generated from members that handle self-assignment correctly handles self-assignment.

Produced in the correct handling of the default assignment will be assigned to members of the self-self-assignment problem.

 

struct Bar {
    vector<pair<int, int>> v;
    map<string, int> m;
    string s;
};

Bar b;
// ...
b = b;   // correct and efficient

 

 

 

Note (Note)

You can handle self-assignment by explicitly testing for self-assignment, but often it is faster and more elegant to cope without such a test (e.g., using swap).

You can prevent self assigned by expressly assigned to self-check, but generally do not use the examination of the treatment (for example, using swap) way faster and more elegant.

 

class Foo {
    string s;
    int i;
public:
    Foo& operator=(const Foo& a);
    // ...
};

Foo& Foo::operator=(const Foo& a)   // OK, but there is a cost
{
    if (this == &a) return *this;
    s = a.s;
    i = a.i;
    return *this;
}

 

This is obviously safe and apparently efficient. However, what if we do one self-assignment per million assignments? That's about a million redundant tests (but since the answer is essentially always the same, the computer's branch predictor will guess right essentially every time). Consider:

This approach seems safe and efficient. But what happens if a case of self-assignment occurs only in one million assignment under it? There are about a million extra checks (but essentially as a result is always the same, the computer branch prediction will always guessed right). Consider the following code:

 

Foo& Foo::operator=(const Foo& a)   // simpler, and probably much better
{
    s = a.s;
    i = a.i;
    return *this;
}

 

std::string is safe for self-assignment and so are int. All the cost is carried by the (rare) case of self-assignment.

std :: string assignment for self safety, int too. All costs are from the (very few) self-assignment occurs.

 

 

Enforcement (Suggestions)

(Simple) Assignment operators should not contain the pattern if (this == &a) return *this; ???

(Simple) assignment operator should not contain the following checks: if (this == & a) return * this;

 


 

I think this article helpful? Welcome thumbs up and share it with more people.

Read more updated articles, please pay attention to micro-channel public number of object-oriented thinking []

发布了408 篇原创文章 · 获赞 653 · 访问量 29万+

Guess you like

Origin blog.csdn.net/craftsman1970/article/details/104680070