跳转到内容
主菜单
主菜单
移至侧栏
隐藏
导航
首页
最近更改
随机页面
MediaWiki帮助
代码酷
搜索
搜索
中文(中国大陆)
外观
创建账号
登录
个人工具
创建账号
登录
未登录编辑者的页面
了解详情
贡献
讨论
编辑“︁
C++ 赋值运算符重载
”︁
页面
讨论
大陆简体
阅读
编辑
编辑源代码
查看历史
工具
工具
移至侧栏
隐藏
操作
阅读
编辑
编辑源代码
查看历史
常规
链入页面
相关更改
特殊页面
页面信息
外观
移至侧栏
隐藏
您的更改会在有权核准的用户核准后向读者展示。
警告:
您没有登录。如果您进行任何编辑,您的IP地址会公开展示。如果您
登录
或
创建账号
,您的编辑会以您的用户名署名,此外还有其他益处。
反垃圾检查。
不要
加入这个!
= C++赋值运算符重载 = 赋值运算符重载是C++中一个重要的特性,它允许程序员自定义类对象之间的赋值行为。通过重载赋值运算符,可以确保对象在赋值时执行特定的操作,如深拷贝、资源管理或其他自定义逻辑。 == 介绍 == 在C++中,赋值运算符(`=`)用于将一个对象的值赋给另一个对象。对于内置类型(如`int`、`float`等),赋值操作是直接且简单的。但对于用户自定义的类类型,默认的赋值运算符可能无法满足需求,尤其是在涉及动态内存分配或其他资源管理时。这时,就需要通过重载赋值运算符来自定义赋值行为。 赋值运算符重载的函数声明通常如下: <syntaxhighlight lang="cpp"> ClassName& operator=(const ClassName& other); </syntaxhighlight> 其中: * `ClassName`是自定义类的名称。 * `operator=`是重载的赋值运算符。 * `const ClassName& other`是被赋值的对象(右值)。 * 返回类型为`ClassName&`,通常返回`*this`以支持链式赋值(如`a = b = c`)。 == 基本语法与示例 == 以下是一个简单的示例,展示如何重载赋值运算符: <syntaxhighlight lang="cpp"> #include <iostream> #include <cstring> class String { private: char* data; size_t length; public: // 构造函数 String(const char* str = "") { length = strlen(str); data = new char[length + 1]; strcpy(data, str); } // 析构函数 ~String() { delete[] data; } // 赋值运算符重载 String& operator=(const String& other) { if (this != &other) { // 防止自赋值 delete[] data; // 释放原有资源 length = other.length; data = new char[length + 1]; strcpy(data, other.data); } return *this; } // 打印字符串 void print() const { std::cout << data << std::endl; } }; int main() { String str1("Hello"); String str2; str2 = str1; // 调用赋值运算符重载 str1.print(); // 输出: Hello str2.print(); // 输出: Hello return 0; } </syntaxhighlight> === 代码解释 === 1. **构造函数**:动态分配内存并初始化字符串。 2. **析构函数**:释放动态分配的内存。 3. **赋值运算符重载**: - 检查自赋值(`if (this != &other)`),避免释放资源后访问无效内存。 - 释放原有资源(`delete[] data`)。 - 分配新内存并复制数据。 - 返回`*this`以支持链式赋值。 4. **输出结果**:`str1`和`str2`的内容相同,表明赋值成功。 == 自赋值问题 == 自赋值(如`a = a`)是一个容易被忽视的问题。如果不检查自赋值,可能会导致资源被提前释放,进而引发未定义行为。例如: <syntaxhighlight lang="cpp"> String& operator=(const String& other) { delete[] data; // 如果 this == &other,data 已被释放 length = other.length; data = new char[length + 1]; strcpy(data, other.data); return *this; } </syntaxhighlight> 如果`this == &other`,`delete[] data`会释放`data`,后续的`strcpy`将访问无效内存。 == 移动赋值运算符(C++11及以上) == C++11引入了移动语义,允许更高效的资源转移。移动赋值运算符的声明如下: <syntaxhighlight lang="cpp"> ClassName& operator=(ClassName&& other); </syntaxhighlight> 示例: <syntaxhighlight lang="cpp"> String& operator=(String&& other) { if (this != &other) { delete[] data; data = other.data; // 转移资源 length = other.length; other.data = nullptr; // 确保 other 析构时不会释放资源 other.length = 0; } return *this; } </syntaxhighlight> === 使用场景 === 移动赋值运算符适用于临时对象(右值)的赋值,避免不必要的拷贝。 == 实际应用案例 == 假设有一个`Matrix`类,表示二维矩阵: <syntaxhighlight lang="cpp"> class Matrix { private: size_t rows, cols; double** data; public: Matrix(size_t rows, size_t cols) : rows(rows), cols(cols) { data = new double*[rows]; for (size_t i = 0; i < rows; ++i) { data[i] = new double[cols](); // 初始化为0 } } ~Matrix() { for (size_t i = 0; i < rows; ++i) { delete[] data[i]; } delete[] data; } Matrix& operator=(const Matrix& other) { if (this != &other) { // 释放原有资源 for (size_t i = 0; i < rows; ++i) { delete[] data[i]; } delete[] data; // 分配新资源并复制数据 rows = other.rows; cols = other.cols; data = new double*[rows]; for (size_t i = 0; i < rows; ++i) { data[i] = new double[cols]; std::copy(other.data[i], other.data[i] + cols, data[i]); } } return *this; } }; </syntaxhighlight> === 说明 === - 动态分配二维数组时,需要逐行释放和复制。 - 使用`std::copy`高效复制数据。 == 总结 == 赋值运算符重载是C++中管理资源的重要工具。关键点包括: 1. 检查自赋值。 2. 释放原有资源。 3. 分配新资源并复制数据。 4. 返回`*this`以支持链式赋值。 5. 在C++11及以上版本中,考虑实现移动赋值运算符以提高性能。 通过合理重载赋值运算符,可以确保类对象在赋值时行为正确且高效。 [[Category:编程语言]] [[Category:C++]] [[Category:C++ 运算符重载]]
摘要:
请注意,所有对代码酷的贡献均被视为依照知识共享署名-非商业性使用-相同方式共享发表(详情请见
代码酷:著作权
)。如果您不希望您的文字作品被随意编辑和分发传播,请不要在此提交。
您同时也向我们承诺,您提交的内容为您自己所创作,或是复制自公共领域或类似自由来源。
未经许可,请勿提交受著作权保护的作品!
取消
编辑帮助
(在新窗口中打开)