Writing move constructors and move assignment

Discussion in 'C++' started by Andrew Tomazos, Dec 12, 2011.

  1. Suppose I have a C interface as follows:

    // create a new FOO
    FOO* foo_open(int params);

    // use FOO one or more times
    void foo_bar(FOO*);

    // destroy FOO
    foo_close(FOO*);

    and I want to wrap that in a C++11 class.

    class Foo
    {
    Foo(int params) : p(foo_open(params)) {}

    void bar() { foo_bar(p); }

    ~Foo() { if (p) { foo_close(p); } }

    private:
    FOO* p;

    // Clearly Foo cannot be copied otherwise you will call foo_close
    twice for the same handle
    Foo(const Foo&) = delete;
    Foo& operator= (const Foo&) = delete;

    // But we should be able to move it
    Foo(Foo&& that)
    {
    ???
    }

    Foo& operator= (Foo&&)
    {
    ???
    }
    };

    I am not clear how to implement the move constructor and move
    assignment. ? What role does std::move play if any in this case?
    -Andrew.
    Andrew Tomazos, Dec 12, 2011
    #1
    1. Advertising

  2. Andrew Tomazos

    Marc Guest

    Andrew Tomazos wrote:

    > Suppose I have a C interface as follows:
    >
    > // create a new FOO
    > FOO* foo_open(int params);
    >
    > // use FOO one or more times
    > void foo_bar(FOO*);
    >
    > // destroy FOO
    > foo_close(FOO*);
    >
    > and I want to wrap that in a C++11 class.
    >
    > class Foo
    > {
    > Foo(int params) : p(foo_open(params)) {}
    >
    > void bar() { foo_bar(p); }
    >
    > ~Foo() { if (p) { foo_close(p); } }
    >
    > private:
    > FOO* p;
    >
    > // Clearly Foo cannot be copied otherwise you will call foo_close
    > twice for the same handle
    > Foo(const Foo&) = delete;
    > Foo& operator= (const Foo&) = delete;
    >
    > // But we should be able to move it
    > Foo(Foo&& that)
    > {
    > ???
    > }
    >


    Foo(Foo&& that):p(that.p){that.p=0;}

    > Foo& operator= (Foo&& that)
    > {
    > ???


    std::swap(p,that.p);

    OR

    foo_close(p); p=that.p; that.p=0;
    (it could be different if foo_close can throw)

    > }
    > };
    >
    > I am not clear how to implement the move constructor and move
    > assignment. ?


    Just try to consider what the destructor can do after you moved from
    an object. Move assignment is often a synonym for swap (avoids
    thinking too long) unless you want to be sure to destruct immediatly.

    > What role does std::move play if any in this case?


    Foo a(42);
    Foo b=std::move(a);
    a=std::move(b);

    You may want to take a look at unique_ptr.
    Marc, Dec 12, 2011
    #2
    1. Advertising

  3. Andrew Tomazos

    Nobody Guest

    On Mon, 12 Dec 2011 04:11:10 -0800, Andrew Tomazos wrote:

    > Foo(Foo&& that)
    > {
    > ???

    p = that.p;
    that.p = NULL;
    > }



    >
    > Foo& operator= (Foo&&)

    Foo& operator= (Foo&& that)
    > {
    > ???

    if (this != &that) {
    p = that.p;
    that.p = NULL;
    }
    return *this
    > }
    > };


    > What role does std::move play if any in this case?


    You can re-write the move constructor using the move assignment
    operator and std::move as:

    Foo(Foo&& that)
    {
    *this = std::move(that);
    }

    std::move just lets you get an rvalue reference for an lvalue, to cause
    the correct overload to be used.
    Nobody, Dec 12, 2011
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Dave Rudolf
    Replies:
    12
    Views:
    8,246
    Martijn Lievaart
    Feb 6, 2004
  2. Jeremy Smith
    Replies:
    2
    Views:
    572
    Jeremy Smith
    Aug 3, 2006
  3. Jess
    Replies:
    5
    Views:
    582
    Ron Natalie
    Jun 7, 2007
  4. Peng Yu
    Replies:
    5
    Views:
    381
    Juha Nieminen
    Sep 19, 2008
  5. srp113
    Replies:
    3
    Views:
    456
Loading...

Share This Page