c++11学习笔记(4)- 移动构造函数与移动语义


 

1.移动构造函数

什么是移动构造函数呢?
我们首先来看一个例子:

该示例的运行结果为:
Object()
Object()
Object(const Object&)

代码main()函数中 Object o1; 执行了一次普通构造函数;函数 getObject 也执行了一次普通构造函数并生成一个临时的 Object 对象,这里由于编译器的优化,这个临时对象就是函数中的obj 本身; o2 对象的创建执行了一次拷贝构造函数。

如果我们能够把函数 getObject 产生的临时对象直接赋值给 o2 那该有多好啊,这样就可以不用使用拷贝构造再重新生成内存了,提升了程序的效率。那么有没有什么办法实现呢,当然是有的,使用移动构造函数,我们在上面的类 Object 中添加如下代码:

程序的运行结果如下:
Object()
Object()
Object(Object&& object)

使用移动构造函数 Object(Object&& object) 将临时对象的堆内存转移到对象o2中,并使用代码object.m_pMem = nullptr; 以便object临时对象能够安全的被析构。
Object&& 实际上上一个 右值引用 ,关于右值引用可以参考上一篇文章
左值、右值和右值引用

在C++中这样“偷走”临时变量中资源的构造函数,就叫做 移动构造函数 ;而这样“偷”的行为就叫做 移动语义。移动语义在资源共享时,可以起到关键的作用。

 

2. std::move

在c++11中,标准库在<utility> 中提供了一个有用的函数 std::move,这个函数并不移动任何东西,他唯一的功能是将一个左值强制转化为右值引用,以用于移动语义

值得一提的是,被转化的左值,其生命周期并没有随着左右值得转化而改变。

我们将上面的代码改写一下:

运行结果为
Object()
Object(Object&& object)
10

可见 o1 并没有因为左右值得转换而被释放。

有了移动语义,我们可以实现一个高效率的置换(swap)函数,代码如下:

如果T是可移动的,那么移动构造和移动赋值将用于这个替换,提高交换的效率;如果T是不可移动的确是可拷贝的,那么拷贝语义将会用于这个置换。

You May Also Like

About the Author: admin

喜欢编程、爱游戏,更爱生活。

发表评论

电子邮件地址不会被公开。