news 2026/5/22 15:08:27

C++移动语义与右值引用

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C++移动语义与右值引用

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++性能优化的重要工具。正确使用移动语义可以避免不必要的拷贝,提高程序效率,但也需要注意异常安全和资源管理。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/22 15:06:47

写论文的学术外挂!专业AI写作辅助平台,秒出初稿不费力

作为一名刚完成毕业论文的过来人&#xff0c;我太懂写论文的痛苦了 —— 选题迷茫、资料查找困难、逻辑不清晰、反复修改、格式混乱、查重压力大... 直到我发现了这套 AI 写作工具组合&#xff0c;简直是论文写作的 "开挂神器"&#xff0c;效率直接拉满&#xff0c;原…

作者头像 李华
网站建设 2026/5/22 15:05:03

解锁PowerToys中文版:让Windows效率工具真正说中文的完整指南

解锁PowerToys中文版&#xff1a;让Windows效率工具真正说中文的完整指南 【免费下载链接】PowerToys-CN PowerToys Simplified Chinese Translation 微软增强工具箱 自制汉化 项目地址: https://gitcode.com/gh_mirrors/po/PowerToys-CN 你知道吗&#xff1f;微软Power…

作者头像 李华
网站建设 2026/5/22 15:02:19

交大樊同学-UMLChina建模答题赛第7赛季第12轮

DDD领域驱动设计批评文集 做强化自测题获得“软件方法建模师”称号 《软件方法》各章合集 参考潘加宇在《软件方法》和UMLChina公众号文章中发表的内容作答。在本文下留言回答。 所有题目的回答必须放在同一条消息中&#xff0c;方为有效回答。同一人多次回答&#xff0c;以…

作者头像 李华
网站建设 2026/5/22 15:01:54

程序员35岁以后最好的投资:不是买房,是这3样东西

当“35岁红线”撞上测试人的职业围城如果你在某个深夜刷到“程序员35岁以后该何去何从”的帖子时&#xff0c;心底划过一丝隐痛&#xff0c;那你绝不是一个人。而对于软件测试从业者而言&#xff0c;这种焦虑往往被放大得更加具体——当“点点点”的手工测试逐渐被自动化替代&a…

作者头像 李华
网站建设 2026/5/22 15:01:44

微信聊天记录永久保存的终极方案:WeChatMsg完全实战解析

微信聊天记录永久保存的终极方案&#xff1a;WeChatMsg完全实战解析 【免费下载链接】WeChatMsg 提取微信聊天记录&#xff0c;将其导出成HTML、Word、CSV文档永久保存&#xff0c;对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com/GitHub_Trending/we/WeC…

作者头像 李华