C ++ core principles C.60: assignment operator copies const & should be based on the parameters, return type of non-const reference virtual function

C.60: Copy the Make non-Assignment Virtual, by const & Take The Parameter, and return by non-const &
C.60: assignment operator copies const & should be based on the parameters, return type of non-const reference virtual function

 

 

Reason (reason)

 

 

It is simple and efficient. If you want to optimize for rvalues, provide an overload that takes a && (see F.18).

Because of this simple and efficient. If you want to optimize the value of the right to provide a use && (rvalue references) overload.

 

Example (Example)

 

 

 

class Foo {
public:
    Foo& operator=(const Foo& x)
    {
        // GOOD: no need to check for self-assignment (other than performance)
        auto tmp = x;
        swap(tmp); // see C.83
        return *this;
    }
    // ...
};

Foo a;
Foo b;
Foo f();

a = b;    // assign lvalue: copy
a = f();  // assign rvalue: potentially move

 

 

Note (Note)

 

 

The swap implementation technique offers the strong guarantee.

Technology swap function (refer to C.83) is provided (copy does not occur since, translator's note) strong guarantee.

 

Example (Example)

 

 

But what if you can get significantly better performance by not making a temporary copy? Consider a simple Vector intended for a domain where assignment of large, equal-sized Vectors is common. In this case, the copy of elements implied by the swap implementation technique could cause an order of magnitude increase in cost:

But you can not pass at least once a temporary copy of the action to be significantly higher performance? Considered for (elements, translator's note) simple scene of the same size Vector Vector huge assignment. In this case, the technical elements realized by copying swap operation will cause a substantial increase in cost.

 

Translator's Note

The previous example, a copy constructor performed before swap

 

template<typename T>
class Vector {
public:
    Vector& operator=(const Vector&);
    // ...
private:
    T* elem;
    int sz;
};

Vector& Vector::operator=(const Vector& a)
{
    if (a.sz > sz) {
        // ... use the swap technique, it can't be bettered ...
        return *this;
    }
    // ... copy sz elements from *a.elem to elem ...
    if (a.sz < sz) {
        // ... destroy the surplus elements in *this and adjust size ...
    }
    return *this;

By writing directly to the target elements, we will get the basic guarantee rather than the strong guarantee offered by the swap technique. Beware of self-assignment.

The data is written directly by the object element, we can get basic security, not strong guarantee provided by the swap technology. In order to prevent ourselves assignment.

 

Alternatives (optional)

 

 

If you think you need a virtual assignment operator, and understand why that's deeply problematic, don't call it operator=. Make it a named function like virtual void assign(const Foo&). See copy constructor vs. clone().

If you think you need a virtual assignment operator, and it will produce a very deep understanding of the problem, do not designed as an assignment operator. It is defined as a named function, e.g. virtual void assign (const Foo &). [Reference] Cloning vs copy constructor.

 

Cloning a copy constructor vs link:

https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Rc-copy-virtual

 

Enforcement (Suggestions)

 

 

  • (Simple) An assignment operator should not be virtual. Here be dragons!

    (Simple) assignment operator should not be virtual. Do very dangerous.

  • (Simple) An assignment operator should return T& to enable chaining, not alternatives like const T& which interfere with composability and putting objects in containers.

    (Simple) assignment operator should return to T &, so as to achieve continuous assignment. Do not change the type const T & Similarly, it will affect and interfere with the assembly of the objects into the container.

  • (Moderate) An assignment operator should (implicitly or explicitly) invoke all base and member assignment operators. Look at the destructor to determine if the type has pointer semantics or value semantics.

    (Average) assignment operator should (implicitly or explicitly) calls the base class and all members of the assignment operator. Destructor was observed to determine the type of pointer semantics of formula or value semantics.

Description link

 

 

https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c60-make-copy-assignment-non-virtual-take-the-parameter-by-const-and-return-by-non-const

 


 

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 []

Published 408 original articles · won praise 653 · views 290 000 +

Guess you like

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