右值引用
为了支持移动操作,C++11增加了右值引用。
使用&&来定义
//int &num=100;//错误的使用方法,引用不能引用常量int &&num=100;//正确的//同样
int b=10;
//int &m=b*9+3;//错误的
int &&m=b*9+3;//正确的//当然,这其中也包括函数的返回值在内
移动构造函数和移动赋值函数
1、移动构造函数
移动构造函数的参数,是一个右值引用。当对象被临时创建兵立即初始化另一个对象的时候,回去调用移动构造函数。与普通构造函数不同,移动构造函数不会创建新对象的副本(不另外创建资源),而是直接使用其对象的内容,直接转移到新的对象。
移动构造传入的参数,一般函数结束后,就无法继续使用了
class MyClass {
public:// 移动构造函数MyClass(MyClass&& other) noexcept : data(other.data) {other.data = nullptr; // 将原始对象的资源置为nullptr,确保它不再拥有这些资源}private:int* data; // 假设MyClass管理动态分配的内存
};
2、移动赋值函数
同上,他需要的参数依旧是一个右值引用。
class MyClass {
public:// 移动赋值运算符MyClass& operator=(MyClass&& other) noexcept {if (this != &other) {delete[] data; // 释放当前对象的资源data = other.data; // 窃取其他对象的资源other.data = nullptr; // 将原始对象的资源置为nullptr}return *this; // 返回当前对象的引用}private:int* data; // 假设MyClass管理动态分配的内存
};
这段代码定义的是 MyClass
类的移动赋值运算符。
移动赋值运算符使用的是右值引用为参数,在这个过程中,当前对象的资源先被释放,然后“窃取”其他对象的资源,并将其他对象的资源指针设置为 nullptr
,确保其他对象不再拥有这些资源。最后,返回当前对象的引用。这是移动语义的典型应用,用于支持异常安全的资源管理。
noexcept
在 C++ 中,noexcept
关键字用于声明一个函数不会抛出异常。它被放置在函数声明的尾部,用来告诉编译器该函数保证不会抛出任何异常。
noexcept
可以被用作函数的属性,以优化程序性能,并确保异常安全。
move
最常见的移动函数。它的主要作用就是,把左值转化成右值。需要引入头文件utility
#include <iostream>
#include <utility>
#include <string>using namespace std;int main()
{string s1 = "quiijie";string s2 = s1;cout << "s1=" << s1 << endl;cout << "s2=" << s2 << endl;string s3 = move(s1);//这里使用了movecout << "s1=" << s1 << endl;//s1已经被销毁掉了cout << "s3=" << s3 << endl;return 0;
}
这里也可以理解成,剪切+复制的操作,非常好理解。
每日金句:
人生就是一场必败的擂台,生老病痛,求之不得每一个都能让你再起不能,最后死亡再给你一记重拳把你打趴下,擂台上有输赢的标准,但评判这条命我们自己才最有资格,输赢不重要,重要的是如何挥出下一拳。 ———尾巴大爷