So how are main classes written in C ++ 11 these days?

Update: I'm using MSVC10 which doesn't give me the default move semantics

Let's say I want to create a regular class with multiple non-pod members;

class Foo {
NonPodTypeA a_;
NonPodTypeB b_;
}

      

As usual, I implement an instance constructor and an assignment operator in which I use a copy constructor:

Foo(const Foo& other) : a_(other.a_), b_(other.b_) {}
Foo& operator=(const Foo& other) { 
  Foo constructed(other);
  *this = std::move(constructed);
  return *this;
}

      

Then I implement move-constructor and move-assign which uses std :: swap instead of std :: move for all members as they can be written before move semantics were available, since move semantics is implemented I can skip the function implementation swap:

Foo(Foo&& other) {
  ::std::swap(a_, other._a);
  ::std::swap(b_, other._b);
}
Foo& operator=(Foo&& other) { 
  ::std::swap(a_, other._a);
  ::std::swap(b_, other._b);
  return *this;
}

      

And here's my question; can I do something more general, assuming I know nothing about members?

For example, the move constructor is not compatible with declared const members, but if I implement the move constructor like Foo(Foo&& other) : a_(std::move(other.a_)), b_(std::move(other.b_)){}

, then I'm not sure if classes without move semantics are not copied? Can I use the move constructor in the move assignment in some clever way?

+3


source to share


2 answers


Um, don't do anything. All these things are created automatically for you 1 . The only time you need to write them by hand is when the class is handling resources (and then you need to follow the Rule of Three ). It's just like it used to be. The only difference is that after you've covered rule three, you might want to implement move elements either semantic (i.e. Create objects just to move) or performance (generally faster than copies).




<sub> 1. MSVC 10 does not create automatic move constructors. In this case, you can write the move elements yourself :(

+6


source


Considering the limitations of MSVC10 and MSVC11 in that you need to write your own move / move mechanisms for assignment operators, the following: I have. I based it on this video from Stephan T. Lavavej.

http://channel9.msdn.com/Shows/Going+Deep/C9-Lectures-Stephan-T-Lavavej-Standard-Template-Library-STL-9-of-n



class Foo 
{
public:

    //Note: don't pass param by reference. Unified assignment operator
    Foo& operator=(Foo other)
    {
        other.swap(*this);
        return *this;
    }

    Foo(Foo&& other)
      : a_(std::move(other.a_),
        b_(std::move(other.b_){}

    Foo(Foo& other)
      : a_(other.a_),
        b_(other.b_){}

private:
    void swap(Foo& other)
    {
        using std::swap;
        swap(a_, other.a_);
        swap(b_, other.b_);
    }

private:
    NonPodTypeA a_;
    NonPodTypeB b_;
};

      

+1


source







All Articles