C++移动语义与右值引用
移动语义是C++11引入的重要特性,通过避免不必要的拷贝操作来提高程序性能。右值引用是实现移动语义的语法基础。
右值引用使用&&语法,可以绑定到临时对象,允许我们"窃取"临时对象的资源。
#include
#include
#include
#include
class Buffer {
size_t size_;
int* data_;
public:
explicit Buffer(size_t size) : size_(size), data_(new int[size]) {
std::cout << "Constructor: allocated " << size_ << " ints\n";
}
~Buffer() {
delete[] data_;
std::cout << "Destructor: freed memory\n";
}
Buffer(const Buffer& other) : size_(other.size_), data_(new int[other.size_]) {
std::copy(other.data_, other.data_ + size_, data_);
std::cout << "Copy constructor: copied " << size_ << " ints\n";
}
Buffer& operator=(const Buffer& other) {
if (this != &other) {
delete[] data_;
size_ = other.size_;
data_ = new int[size_];
std::copy(other.data_, other.data_ + size_, data_);
std::cout << "Copy assignment: copied " << size_ << " ints\n";
}
return *this;
}
Buffer(Buffer&& other) noexcept : size_(other.size_), data_(other.data_) {
other.size_ = 0;
other.data_ = nullptr;
std::cout << "Move constructor: moved " << size_ << " ints\n";
}
Buffer& operator=(Buffer&& other) noexcept {
if (this != &other) {
delete[] data_;
size_ = other.size_;
data_ = other.data_;
other.size_ = 0;
other.data_ = nullptr;
std::cout << "Move assignment: moved " << size_ << " ints\n";
}
return *this;
}
size_t size() const { return size_; }
};
void move_semantics_basic() {
Buffer buf1(1000);
Buffer buf2 = std::move(buf1);
std::vector vec;
vec.push_back(Buffer(500));
vec.push_back(Buffer(600));
}
std::move将左值转换为右值引用,允许移动操作发生。
template
void process_value(T&& value) {
std::cout << "Processing rvalue reference\n";
}
void process_value(int& value) {
std::cout << "Processing lvalue reference\n";
}
void move_example() {
int x = 42;
process_value(x);
process_value(std::move(x));
process_value(100);
}
完美转发使用std::forward保持参数的值类别,在模板中传递参数时非常有用。
template
std::unique_ptr make_unique(Args&&... args) {
return std::unique_ptr(new T(std::forward(args)...));
}
class Widget {
std::string name_;
int value_;
public:
Widget(const std::string& name, int value)
: name_(name), value_(value) {
std::cout << "Widget constructed with lvalue string\n";
}
Widget(std::string&& name, int value)
: name_(std::move(name)), value_(value) {
std::cout << "Widget constructed with rvalue string\n";
}
void display() const {
std::cout << "Widget: " << name_ << " = " << value_ << "\n";
}
};
void perfect_forwarding_example() {
std::string name = "test";
auto w1 = make_unique(name, 42);
auto w2 = make_unique("temp", 100);
w1->display();
w2->display();
}
移动语义在容器操作中可以显著提高性能。
void container_move_example() {
std::vector vec1;
for (int i = 0; i < 5; ++i) {
vec1.push_back(std::string(1000, 'a' + i));
}
std::cout << "Moving vector...\n";
std::vector vec2 = std::move(vec1);
std::cout << "vec1 size: " << vec1.size() << "\n";
std::cout << "vec2 size: " << vec2.size() << "\n";
}
返回值优化和移动语义结合,可以实现高效的函数返回。
Buffer create_buffer(size_t size) {
Buffer buf(size);
return buf;
}
void return_value_optimization() {
Buffer buf = create_buffer(1000);
std::cout << "Buffer size: " << buf.size() << "\n";
}
移动迭代器允许在算法中使用移动语义。
#include
#include
void move_iterator_example() {
std::vector source;
for (int i = 0; i < 5; ++i) {
source.push_back(std::string(100, 'a' + i));
}
std::vector dest;
dest.reserve(source.size());
std::move(std::make_move_iterator(source.begin()),
std::make_move_iterator(source.end()),
std::back_inserter(dest));
std::cout << "Source size after move: " << source.size() << "\n";
std::cout << "Dest size: " << dest.size() << "\n";
}
引用限定符允许根据对象的值类别选择不同的成员函数。
class Data {
std::vector values_;
public:
Data() : values_{1, 2, 3, 4, 5} {}
std::vector& get() & {
std::cout << "Returning lvalue reference\n";
return values_;
}
std::vector get() && {
std::cout << "Returning by move\n";
return std::move(values_);
}
};
void ref_qualifier_example() {
Data data;
auto& ref = data.get();
auto moved = Data().get();
}
移动语义与异常安全需要特别注意,移动操作应该标记为noexcept。
class SafeBuffer {
size_t size_;
int* data_;
public:
explicit SafeBuffer(size_t size) : size_(size), data_(new int[size]) {}
~SafeBuffer() {
delete[] data_;
}
SafeBuffer(SafeBuffer&& other) noexcept
: size_(other.size_), data_(other.data_) {
other.size_ = 0;
other.data_ = nullptr;
}
SafeBuffer& operator=(SafeBuffer&& other) noexcept {
if (this != &other) {
delete[] data_;
size_ = other.size_;
data_ = other.data_;
other.size_ = 0;
other.data_ = nullptr;
}
return *this;
}
SafeBuffer(const SafeBuffer&) = delete;
SafeBuffer& operator=(const SafeBuffer&) = delete;
};
void exception_safety_example() {
std::vector vec;
vec.reserve(10);
for (int i = 0; i < 5; ++i) {
vec.push_back(SafeBuffer(100));
}
std::cout << "Vector size: " << vec.size() << "\n";
}
移动语义是现代C++性能优化的重要工具。正确使用移动语义可以避免不必要的拷贝,提高程序效率,但也需要注意异常安全和资源管理。
C++移动语义与右值引用
张小明
前端开发工程师
Upscayl Vulkan错误终极解决指南:AI图像超分辨率内存与队列问题深度解析
Upscayl Vulkan错误终极解决指南:AI图像超分辨率内存与队列问题深度解析 【免费下载链接】upscayl 🆙 Upscayl - #1 Free and Open Source AI Image Upscaler for Linux, MacOS and Windows. 项目地址: https://gitcode.com/GitHub_Trending/up/upscay…
写论文的学术外挂!专业AI写作辅助平台,秒出初稿不费力
作为一名刚完成毕业论文的过来人,我太懂写论文的痛苦了 —— 选题迷茫、资料查找困难、逻辑不清晰、反复修改、格式混乱、查重压力大... 直到我发现了这套 AI 写作工具组合,简直是论文写作的 "开挂神器",效率直接拉满,原…
解锁PowerToys中文版:让Windows效率工具真正说中文的完整指南
解锁PowerToys中文版:让Windows效率工具真正说中文的完整指南 【免费下载链接】PowerToys-CN PowerToys Simplified Chinese Translation 微软增强工具箱 自制汉化 项目地址: https://gitcode.com/gh_mirrors/po/PowerToys-CN 你知道吗?微软Power…
交大樊同学-UMLChina建模答题赛第7赛季第12轮
DDD领域驱动设计批评文集 做强化自测题获得“软件方法建模师”称号 《软件方法》各章合集 参考潘加宇在《软件方法》和UMLChina公众号文章中发表的内容作答。在本文下留言回答。 所有题目的回答必须放在同一条消息中,方为有效回答。同一人多次回答,以…
程序员35岁以后最好的投资:不是买房,是这3样东西
当“35岁红线”撞上测试人的职业围城如果你在某个深夜刷到“程序员35岁以后该何去何从”的帖子时,心底划过一丝隐痛,那你绝不是一个人。而对于软件测试从业者而言,这种焦虑往往被放大得更加具体——当“点点点”的手工测试逐渐被自动化替代&a…
微信聊天记录永久保存的终极方案:WeChatMsg完全实战解析
微信聊天记录永久保存的终极方案:WeChatMsg完全实战解析 【免费下载链接】WeChatMsg 提取微信聊天记录,将其导出成HTML、Word、CSV文档永久保存,对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com/GitHub_Trending/we/WeC…