默认复制构造函数和复制赋值操作符和以前的类似,C++中新的的东西是基于上述移动语义的精神实现的移动构造函数和移动赋值操作符。运行上面这段程序时会发现,b4在构造时调用了移动构造函数,b1被赋值时调用了移动赋值操作符。原因是getBuffer()函数的返回值是一个临时量,即是一个右值。
  你或许已经注意到了移动构造函数中初始化名字变量和指向缓存的指针时使用到的std::move。名字变量实际上是string类型,而std::string和std::unique_ptr一样也实现了移动语义。如果我们说通过_name(temp._name)语句复制构造函数将被调用,但对于_buffer来说这不可能,因为std::unique_ptr连复制构造函数都没有。然而这种情况下std::string的移动构造函数为什么没有被调用呢?因为尽管移动构造函数为Buffer调用的对象是一个右值,但在构造函数内部实际上它是一个左值。为什么?因为它有一个叫作“temp”的名字,而有名字的对象是一个左值。使用std::move的目的是让它再次成为一个右值(以便调用适当的移动构造函数)。std::move函数的作用是将一个左值引用转换为一个右值引用。
  更新:尽管这个例子的目的是演示移动构造函数和移动赋值操作符的实现方式,但具体的实现细节却大有不同。评论中的Member 7805758提供了一种实现方式,为了阅读方便写到了正文中:
1 template <typename T>
2 class Buffer
3 {
4     std::string          _name;
5     size_t               _size;
6     std::unique_ptr<T[]> _buffer;
7
8 public:
9     // constructor
10     Buffer(const std::string& name = "", size_t size = 16):
11         _name(name),
12         _size(size),
13         _buffer(size ? new T[size] : nullptr)
14     {}
15
16     // copy constructor
17     Buffer(const Buffer& copy):
18         _name(copy._name),
19         _size(copy._size),
20         _buffer(copy._size ? new T[copy._size] : nullptr)
21     {
22         T* source = copy._buffer.get();
23         T* dest = _buffer.get();
24         std::copy(source, source + copy._size, dest);
25     }
26
27     // copy assignment operator
28     Buffer& operator=(Buffer copy)
29     {
30         swap(*this. copy);
31         return *this;
32     }
33
34     // move constructor
35     Buffer(Buffer&& temp):Buffer()
36     {
37         swap(*this, temp);
38     }
39
40     friend void swap(Buffer& first, Buffer& second) noexcept
41     {
42         using std::swap;
43         swap(first._name   , second._name);
44         swap(first._size   , second._size);
45         swap(first._buffer , second._buffer);
46     }
47 };
  总结
  还有许多关于C++11的东西可以讨论,这仅仅只是一个开始。本文展示了C++开发者都会用到的一些核心语言和标准库中的特性,我建议至少对于其中的一些特性再找些其它文章做进一步的学习。
  许可
  本文及相关源代码和文件遵循CPOL许可。