When should we write our own assignment operator in C++?
The answer is same as Copy Constructor. If a class doesn’t contain pointers, then there is no need to write assignment operator and copy constructor. The compiler creates a default copy constructor and assignment operators for every class.
The compiler created copy constructor and assignment operator may not be sufficient when we have pointers or any run time allocation of resource like file handle, a network connection..etc. For example, consider the following program.
1 #include<iostream>
2 using namespace std;
3
4 // A class without user defined assignment operator
5 class Test
6 {
7 int *ptr;
8 public:
9 Test (int i = 0)
10 {
11 ptr = new int(i);
12 }
13 void setValue (int i)
14 {
15 *ptr = i;
16 }
17 void print()
18 {
19 cout << *ptr << endl;
20 }
21 };
22
23 int main()
24 {
25 Test t1(5);
26 Test t2;
27 t2 = t1;
28 t1.setValue(10);
29 t2.print();
30 return 0;
31 }
Output of above program is “10″.
If we take a look at main(), we modified ‘t1′ using setValue() function, but the changes are also reflected in object ‘t2′. This type of unexpected changes cause problems.
Since there is no user defined assignment operator in the above program, compiler creates a default assignment operator, which copies ‘ptr’ of right hand side to left hand side. So both ‘ptr’s start pointing to the same location.
We can handle the above problem in two ways.
1) Do not allow assignment of one object to other object. We can create our own dummy assignment operator and make it private.
2) Write your own assignment operator that does deep copy.
Same is true for Copy Constructor.
Following is an example of overloading assignment operator for the above class.
1 #include<iostream>
2 using namespace std;
3
4 class Test
5 {
6 int *ptr;
7 public:
8 Test (int i = 0)
9 {
10 ptr = new int(i);
11 }
12 void setValue (int i)
13 {
14 *ptr = i;
15 }
16 void print()
17 {
18 cout << *ptr << endl;
19 }
20 Test & operator = (const Test &t);
21 };
22
23 Test & Test::operator = (const Test &t)
24 {
25 // Check for self assignment
26 if(this != &t)
27 {
28 *ptr = *(t.ptr);
29 }
30
31 return *this;
32 }
33
34 int main()
35 {
36 Test t1(5);
37 Test t2;
38 t2 = t1;
39 t1.setValue(10);
40 t2.print();
41 return 0;
42 }
Output:5
We should also add a copy constructor to the above class, so that the statements like “Test t3 = t4;” also don’t cause any problem.
Note the if condition in assignment operator. While overloading assignment operator, we must check for self assignment(认同测试). Otherwise assigning an object to itself may lead to unexpected results (See this). Self assignment check is not necessary for the above ‘Test’ class, because ‘ptr’ always points to one integer and we may reuse the same memory.
But in general, it is a recommended practice to do self-assignment check.
补充:
C++ doesn't allow default assignment operator to be used when there is a reference in your class.
For example, the following program produces error "error C2582: 'Test' : 'operator =' function is unavailable".
1 #include<iostream>
2 using namespace std;
3
4
5 class Test
6 {
7 int x;
8 int &ref;
9 public:
10 Test (int i):x(i),ref(x)
11 {
12 }
13 void print()
14 {
15 cout << ref;
16 }
17 void setX(int i)
18 {
19 x = i;
20 }
21 //Test &operator = (const Test &t) {x = t.x;}
22 };
23
24
25 int main()
26 {
27 Test t1(10);
28 Test t2(20);
29 t2 = t1;
30 t1.setX(40);
31 t2.print();
32 return 0;
33 }
If you uncomment the operator definition in the above program, the program works fine and prints "10".
So compiler forces to write an assignment operator when you have a non-static reference in your class.
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
转载请注明:http://www.cnblogs.com/iloveyouforever/
2013-11-26 21:35:48
When should we write our own assignment operator in C++?的更多相关文章
- Lintcode208 Assignment Operator Overloading (C++ Only) solution 题解
[题目描述] Implement an assignment operator overloading method. Make sure that: The new data can be copi ...
- Effective C++ 第0章 copy constructor和copy assignment operator
拷贝构造函数(copy constructor)被用来以一个对象来初始化同类型的另一个对象,拷贝赋值运算符(copy assignment operator)被用来将一个对象中的值拷贝到同类型的另一个 ...
- copy constructor和copy assignment operator的区别
拷贝构造函数(copy constructor)被用来以一个对象来初始化同类型的另一个对象,拷贝赋值运算符(copy assignment operator)被用来将一个对象中的值拷贝到同类型的另一个 ...
- Default Assignment Operator and References
We have discussed assignment operator overloading for dynamically allocated resources here . This is ...
- Copy constructor vs assignment operator in C++
Difficulty Level: Rookie Consider the following C++ program. 1 #include<iostream> 2 #include&l ...
- How to use base class's assignment operator in C++
看了android下的代码,好长时间没看了,有个关于C++的知识点不是很清楚,查了下: 如何使用基类中的赋值运算符? 引述自http://stackoverflow.com/questions/122 ...
- PythonStudy——赋值运算符 Assignment operator
eg: num = 10 num += 1 # 等价于 num = num + 1 => 11 print(num) 特殊操作: 1.链式赋值 a = b = num print(a, b, n ...
- c++, 派生类的构造函数和析构函数 , [ 以及operator=不能被继承 or Not的探讨]
说明:文章中关于operator=实现的示例,从语法上是对的,但逻辑和习惯上都是错误的. 参见另一篇专门探究operator=的文章:<c++,operator=>http://www.c ...
- C++ operator overload -- 操作符重载
C++ operator overload -- 操作符重载 2011-12-13 14:18:29 分类: C/C++ 操作符重载有两种方式,一是以成员函数方式重载,另一种是全局函数. 先看例子 # ...
随机推荐
- 你们不要再吵了! Java只有值传递..
写在前边 上次聊到Java8新特性 lambda时,有小伙伴在评论区提及到了lambda对于局部变量的引用,补充着博客的时候,知识点一发散就有了这篇对于值传递还是引用传递的思考.关于这个问题为何会有如 ...
- WebRTC概念介绍
WebRTC WebRTC(Web Real-Time Communication).Real-Time Communication,实时通讯. WebRTC能让web应用和站点之间选择性地分享音视频 ...
- MySQL之DDL数据定义语言:库、表的管理
库的管理 常用命令 #创建库 create database if not exists 库名 [ character set 字符集名]; create database if not exists ...
- js事件常用操作、事件流
注册事件 给元素添加事件,称为注册事件或者绑定事件. 注册事件有两种方式:传统方式和方法监听注册方式 传统方式 on开头的事件,例如onclick <button onclick="a ...
- redis异常:(error) MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk.
(error) MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on d ...
- FZU ICPC 2020 寒假训练 2
A - 排序 输入一行数字,如果我们把这行数字中的'5'都看成空格,那么就得到一行用空格分割的若 干非负整数(可能有些整数以'0'开头,这些头部的'0'应该被忽略掉,除非这个整数就是由 若干个'0'组 ...
- 基于EPPlus和NPOI实现的Excel导入导出
基于EPPlus和NPOI实现的Excel导入导出 CollapseNav.Net.Tool.Excel(NuGet地址) 太长不看 导入 excel 文件流将会转为 ExcelTestDto 类型的 ...
- [51nod1237]最大公约数之和V3
$\sum_{i=1}^{n}\sum_{j=1}^{n}gcd(i,j)\\$ $=\sum_{d=1}^{n}d\sum_{i=1}^{n/d}\sum_{j=1}^{n/d}\varepsilo ...
- JavaScript 函数声明和变量声明
声明语句:声明语句是用来声明或定义标识符(变量和函数名)并给其赋值. 1:var 变量声明(5.3.1节): var语句用来声明一个或多个变量:var name_1 = [= value_1] [ , ...
- P1759 通天之潜水(双写法+解析)
算法解析 动态规划问题满足三大重要性质 最优子结构性质:如果问题的最优解所包含的子问题的解也是最优的,我们就称该问题具有最优子结构性质(即满足最优化原理).最优子结构性质为动态规划算法解决问题提供了重 ...