Item 25: consider implementing a swap valid tive C ++ note, swapvalid tive

Source: Internet
Author: User

Item 25: consider implementing a swap valid tive C ++ note, swapvalid tive

Item 25: Consider support for a non-throwing swap.

The Swap function was initially introduced by STL and has become a key function in exceptional security programming (see Item 29). It also solves the problem of self-assignment (see Item 11: assignment operator self-assignment).stdIts basic implementation is intuitive:

namespace std{    template<typename T>    void swap(T& a, T& b){        T tmp(a);        a = b;        b = tmp;    }}

As you can see, the above Swap is implemented by assigning values and copying structures. Sostd::swapException security is not provided, but due to the importance of Swap operations, we should implement exception security for custom classes. This is the focus of this section.

Class Swap

Do not mention exceptional security first, sometimesstd::swapNot efficient (for custom types ). For example, in a class designed using pimpl idiom (see Item 31), you only need to exchange pointers to implement objects:

Class WidgetImpl; class Widget {// a class of pimpl idiom WidgetImpl * pImpl; // point to the Widget implementation (data) public: Widget (const Widget & rhs );}; namespace std {template <> // The template parameter is null, indicating that this is a fully-specialized void swap <Widget> (Widget & a, Widget & B) {swap (. pImpl, B. pImpl); // you only need to swap the pointers of their object classes }}

The above Code cannot be compiled becausepImplIs a private member! So,WidgetAswapMember function or friend function. In practice, a member function is provided:

Class Widget {public: void swap (Widget & other) {using std: swap; // Why? See the following swap (pImpl, other. pImpl );}};

Next, we will continue to make it special.std::swapBecause this is the Swap function that can be called:

Namespace std {template <> void swap <Widget> (Widget & a, Widget & B) {a. swap (B); // call the member function }}

So far, we have achieved perfection.swapCode. The above implementation is consistent with that of the STL container: provide a commonswapMember functions, and specialstd::swapTo call the member function.

Class template Swap

WhenWidgetIs a class template, the situation is more complex. According to the above Swap implementation method, you may write as follows:

Template <typename T> class WidgetImpl {...}; template <typename T> class Widget {...}; namespace std {template <typename T> // The angle brackets after swap indicate that this is a special feature, not a heavy load. // The type list in swap <> is a special case of the type list in template <>. Void swap <Widget <T> (Widget <T> & a, Widget <T> & B) {a. swap (B );}}

The tragedy is that the above Code cannot be compiled. C ++ allows bitwise class templates, but does not allow bitwise function templates (although some compilers can compile ). So we simply don't want to be special, so we will reload it.std::swapFunction template:

Namespace std {template <typename T> // note that swap is not followed by Angle brackets. This is a new template function. // The current namespace already has functions with the same name, so the function is overloaded. Void swap (Widget <T> & a, Widget <T> & B) {a. swap (B );}}

Here we reloadstd::swap, Which is equivalentstdA function template is added to the namespace. This is not allowed in the C ++ standard! In the C ++ standard, the customer can only specializestdBut not allowed instdAdd any new template to the namespace. Although the above Code can be compiled in Some compilers, it will lead to undefined behaviors, so do not do this!

What should we do? The solution is also very simple, that is, do notstdAddswapFunctionswapDefined inWidgetIn the namespace:

namespace WidgetStuff {    template<typename T>     class Widget { ... };    template<typename T>     void swap(Widget<T>& a, Widget<T>& b){        a.swap(b);    }}

Anywhere in twoWidgetOnswapC ++ will findWidgetStuffTheWidgetParameterswap.

It seems that Swap of the class only needs to be defined in the same namespace.swapFunction without specialstd::swap. But! Some people prefer to write directlystd::swap(w1, w2), Specialstd::swapIt makes your class more robust.

Because the call is specifiedstd::swap, Argument-dependent lookup becomes invalid,WidgetStuff::swapWill not be called.

Speaking of this, you may ask if I want to give priorityWidgetStuff::swapIf not defined, callstd::swap, How should I write it? Check the Code:

Template <typename T> void doSomething (T & obj1, T & obj2) {using std: swap; // make 'std :: swap 'SWAp (obj1, obj2) is visible in this scope; // now, the compiler will help you select the best swap}

At this time, the C ++ compiler will give priority to calling the specified Tstd::swap, Followedobj1TypeTCorresponding to the namespaceswapFunction.std::swap.

Best practices

How to Implement Swap? Summary:

  1. Provides a more efficient common member function without throwing exceptions (for exampleWidget::swap).
  2. Provide non-member functions in the same namespace of your class (or class template)swapTo call your member functions.
  3. If you are writing a class instead of a class template, please turn it specialstd::swapYou should also call your member functions.
  4. UseusingEnablestd::swapVisible, and then directly callswap.

Unless indicated, this blog post is original, reprinted please in the form of a link to indicate the address: http://harttle.com/2015/08/23/effective-cpp-25.html

Copyright Disclaimer: This article is the original article of the blogger. For more information, see the original article link.

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.