C++移动语义与完美转发
移动语义:
浅拷贝:拷贝只是简单的赋值,两个指针指向同一块内存,析构时容易析构两次,造成内存泄露
深拷贝:拷贝会重新开辟内存,两个指针指向不同的内存,不会造成内存泄露问题*
移动语义:通过移动构造函数,转移资源的所有权,将对方的资源转移到自己身上,对方将失去对该资源的所有权(窃取)
#include <iostream>
using namespace std;
class A {
public:
A(int size) : size_(size) {
data_ = new int[size];
}
A() {}
A(const A& a) {
size_ = a.size_;
data_ = new int[size_];
cout << "copy..." << endl;
}
A(A&& a) {
this->data_ = a.data_;
a.data_ = nullptr;
cout << "move..." << endl;
}
~A() {
if (data_ != nullptr) {
delete[] data_;
cout << "~A()..." << endl;
}
}
public:
int* data_;
int size_;
};
int main()
{
A a(10);
A b = a;
A c = std::move(a); // 调用移动构造函数
return 0;
}
完美转发:
C++中的完美转发(Perfect Forwarding)是指在函数中传递参数,
并将这些参数原封不动地传递给其他函数,保持参数类型和引用性质不变。
完美转发通常与C++11之后引入的右值引用(Rvalue Reference)和std::forward函数一起使用。
完美转发通常用于泛型编程和模板中,以确保传递的参数类型与原始参数类型一致,同时保持右值引用和左值引用的性质。(万能引用)
#include <iostream>
using namespace std;
void PrintV(int &t) {
cout << "lvalue" << endl;
}
void PrintV(int &&t) {
cout << "rvalue" << endl;
}
// 完美转发
template<typename T>void Test(T &&t) {
PrintV(t);
PrintV(std::forward<T>(t));
PrintV(std::move(t));
}
int main() {
Test(1); // lvalue rvalue rvalue
cout << "========" << endl;
int a = 1;
Test(a); // lvalue lvalue rvalue
cout << "========" << endl;
Test(std::forward<int>(a)); // lvalue rvalue rvalue
cout << "========" << endl;
Test(std::forward<int&>(a)); // lvalue lvalue rvalue
cout << "========" << endl;
Test(std::forward<int&&>(a)); // lvalue rvalue rvalue
return 0;
}