Writing move constructors and move assignment

A

Andrew Tomazos

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.
 
M

Marc

Andrew said:
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.
 
N

Nobody

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.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,534
Members
45,007
Latest member
obedient dusk

Latest Threads

Top