f



Writing move constructors and move assignment

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.

0
andrew3888 (273)
12/12/2011 12:11:10 PM
comp.lang.c++ 49423 articles. 6 followers. Post Follow

2 Replies
483 Views

Similar Articles

[PageSpeed] 3

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.
0
marc.glisse (239)
12/12/2011 1:15:51 PM
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.

0
nobody (5159)
12/12/2011 1:45:17 PM
Reply: