1

I was reading C++11 Faq and came across this code. I have a better understanding of C++ coding, but I'm still not able to understand the below code.

    template<class T>
    class Handle {
        T* p;
    public:
        Handle(T* pp) : p{pp} {}
        ~Handle() { delete p; } // user-defined destructor: no implicit copy or move 

        Handle(Handle&& h) :p{h.p} { h.p=nullptr; };    // transfer ownership
        Handle& operator=(Handle&& h) { delete p; p=h.p; h.p=nullptr; return *this; }   // transfer ownership

        Handle(const Handle&) = delete;     // no copy
        Handle& operator=(const Handle&) = delete;

        // ...
    };
  • What does "transfer ownership" mean?
  • Why is the copy ctor equated to "delete"? how is it useful?

Please if someone can add a few examples with explanation, it would be a great help.

Community
  • 1
  • 1
user2598064
  • 157
  • 1
  • 13

4 Answers4

1

It's a move constructor, the special && syntax introduced in C++11 takes a rvalue reference, so a reference to a variable which has no name and can't be referenced anywhere else inside the code.

What happens in the constructor is that the Handle takes the ownership of the Handle passed through the move constructor in the way that it steals (pass me the term) the T* p inside by assigning its value to its own variable and then setting nullptr to the variable of the rvalue passed.

This is used because you don't really need to copy an rvalue, since that value won't be used anymore in the code, so it's safe to just take its data, this avoids a, possibly costly, copy constructor.

Jack
  • 131,802
  • 30
  • 241
  • 343
0

In C++ you had copy constructors and copy operators, which were expensive if your object was big. Now in C++11 you have move constructor and move operator which says "take everything from the source and kill it".

mybigthing y ;
...
mybigthing x( move(y)) ;

y is created with lots of stuff internally. after x(y), y is now empty and all the big stuff is in x.

One of the main reasons for this is to make returning big objects from functions free:

mybigthing f()
{
  mybigthing tmp ;
  ...
  return tmp ;
}

{
  mybigthing y= f() ;
}

In c++03, this would be horrible performance wise. Now its free. The compilers are required to actually use y as the temporary inside of f() and never do any copies.

woolstar
  • 5,063
  • 20
  • 31
0

transfer ownership means if you do a=b the contents of b belong to a and does not exist in b anymore. This makes more sense in the example {A a; dosomething(a); return a;}. a exist locally in the function. It's contents are being moved into the return value. If A is a typedef for std::string it would mean the string internals have been moved instead of making a copy of a intentionally long string (html page maybe). However I believe string has a copy on write flag so it wouldn't make a copy in that situation but other classes may not bother to implement a copy on write.

The reason the constructor and assignment operator (which are move, not copy) delete is because the current p may be pointing to something. Not freeing it means a memory leak.

0

about your second question: Why is the copy ctor equated to "delete"? how is it useful?

Here is an answer: http://www.developerfusion.com/article/133063/constructors-in-c11/

C++11 Explicitly Deleted Constructors

C++11 also supports the concept of explicitly deleted constructors. For example, you can define a class for which you do not want to write any constructors and you also do not want the compiler to generate the default constructor. In that case you need to explicitly delete the default constructor:

class MyClass { public: MyClass() = delete; };

JeanPhi
  • 127
  • 1
  • 11