Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating not copyable, but movable, objects in c++

Just a question. Looking at C++ Boost libraries (in particular boost::thread class) I ended up thinking: "how is it possible to create a class defining objects that cannot be copied but that can be returned from a function?"

Well consider this example, the boost::thread class has the characteristics I mentioned before, so it is possible to do this:

boost::thread make_thread();

void f()
{
    boost::thread some_thread=make_thread();
    some_thread.join();
}

Well this means that the object boost::thread cannot be copied, but returned from a function, this is possible. How is this possible????

I suppose that a copy constructor must not be provided, but how to deal with returning from a function? doesn't it need to use a copy constructor???

Thankyou

like image 254
Andry Avatar asked Nov 23 '10 19:11

Andry


People also ask

How do you make a class not copyable?

There are three ways to prevent such an object copy: keeping the copy constructor and assignment operator private, using a special non-copyable mixin, or deleting those special member functions. A class that represents a wrapper stream of a file should not have its instance copied around.

What is boost Noncopyable?

Boost::noncopyable prevents the classes methods from accidentally using the private copy constructor.


1 Answers

This will be possible in C++1x, which provides move semantics via rvalue references. Using this you can implement moving and/or copying separatedly:

class my_class {
  private:
    data_t* data_;
  public:
    my_class(const my_class& rhs)      // copy constructor
     : data_(rhs.data_.clone())
    {}
    my_class(my_class&& rhs)           // move constructor
     : data_(rhs.data_)
    {
      rhs.data_ = NULL;
    }
    ~my_class() {delete data_;}        // noop if data_==NULL

    my_class& operator=(my_class rhs)  // copy assignment
    {
      this->swap(rhs);
    }
    my_class& operator=(my_class&& rhs)// move assignment
    {
      this->swap(rhs);
    }

    // ...
};

Copying and moving can be forbidden separately, so you can setup classes that can be moved, but not copied.

Of course, there are a few magical tricks that let you do this even when your compiler doesn't yet support move semantics (std::auto_ptr, after all moves instead of copying when assigned to), so this might work for boost::thread even in the absence of move semantics.

like image 192
sbi Avatar answered Oct 15 '22 04:10

sbi