右值引用
为了支持移动操作,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);//这里使用了move
cout << "s1=" << s1 << endl;//s1已经被销毁掉了
cout << "s3=" << s3 << endl;
return 0;
}
这里也可以理解成,剪切+复制的操作,非常好理解。
每日金句:
人生就是一场必败的擂台,生老病痛,求之不得每一个都能让你再起不能,最后死亡再给你一记重拳把你打趴下,擂台上有输赢的标准,但评判这条命我们自己才最有资格,输赢不重要,重要的是如何挥出下一拳。 ———尾巴大爷