赋值运算符重载引发的思考(引用的功能) http://blog.csdn.net/yorkcai/article/details/8567441
来源:互联网 发布:测量软件手机版 编辑:程序博客网 时间:2024/05/16 15:53
- #include <iostream>
- #include "string.h"
- using namespace std;
- class CMessage {
- private:
- char* Message;
- public:
- CMessage(char* MessageText = "Default Text!") {
- cout<<"Constructor called!"<<endl;
- Message = new char[strlen(MessageText) + 1];
- strcpy(Message, MessageText);
- }
- void ShowMessage() {
- cout<<"The message is "<<Message<<endl;
- }
- ~CMessage() {
- cout<<"Destructor Called!"<<endl;
- cout << "Delete data" <<endl;
- delete[] Message;
- }
- CMessage& operator =(const CMessage& OtherObject) {
- cout << "override assignment operator function" <<endl;
- if (this != &OtherObject)//检查对象是否已经赋值给自身
- {
- delete [] Message;
- Message = new char[strlen(OtherObject.Message) + 1];
- strcpy(Message, OtherObject.Message);
- }
- return *this;
- }
- };
- int main(int argc, char* argv[]) {
- CMessage message1("awei is the best!");
- CMessage message2;
- CMessage message3("abcdefadfadf");
- message2 = message1;
- message1.ShowMessage();
- message2.ShowMessage();
- /*
- (message1=message2)=message3;
- message1.ShowMessage();
- message2.ShowMessage();
- message3.ShowMessage();
- */return 0;
- }
如果我们不重载赋值运算符,那么类会自动为我们提供一个赋值运算符,这个默认的赋值运算符函数跟默认的复制构造函数是一样的,就是把一个对象的数据成员的值复制给另一个对象对应的数据成员,在做此测试时,我也遇到了一个问题,直接利用默认赋值函数,引发内存溢出的问题,
代码及原因解释如下:
//////////////////////////////////////////////////////////////////////////
//如果不重载赋值运算符,则下面这条语句
//messge2 = message1;
//将出现很低级的错误,因为这样的话两个成员变量message1和message2指针指向同一块内存地址,
//在程序退出后,第一次调用调用message2的析构函数,则Message指针的地址已经释放,此时再次调用
//message2的析构函数,即是对同一块内存第二次调用delete,那么将出现内存泄漏现象
//////////////////////////////////////////////////////////////////////////
那么我们自己重载了赋值运算符,其参数和返回值为什么要非是引用类型不可呢?
我试着将赋值运算符函数的形参改为CMessage对象,此时再次爆发内存错误,原因是:
当我们以CMessage对象作为实参传入函数时,是以按值传递方式进行的,此时在函数内部将创建一个实参的副本,当函数返回时,该实参副本将被自动清除,实参副本中的Message指针将被释放,由于该指针指向的是对象message2的Message变量所指向的地址,因此message2对象的成员变量所指向的地址就这样莫名其妙的消失了,这样的错误编译时无法发现,但是运行时就会发生错误。运行结果为:
Constructor called!
Constructor called!
Destructor Called!
The message is 葺葺葺葺葺葺葺葺葺葺葺葺
The message is awei is the best!
Destructor Called!
Destructor Called!
当把返回类型改为CMessage对象时,此时跟上述情况雷同,此时赋值函数返回的message2原始对象的临时副本,当它销毁后,用来接收返回值的CMessage对象的Message所指向的指针也随之销毁,输出如下:
Constructor called!
Constructor called!
Destructor Called!
The message is awei is the best!
The message is 葺葺葺葺葺葺葺葺葺葺葺葺
Destructor Called!
此外,当使用(message1 = message2) = message3这样的表达式时,也是不合法的,因为左边表达式的返回结果是message1对象的临时副本,而编译器是不允许利用临时对象来调用成员函数的。
因此,这种情况是必须使用引用来传递参数和返回参数的,而且引用返回值的主要特性是可以作为左值,我们可以在赋值语句左边使用返回引用的函数,如表达式:(message1 = message2) = message3
- 赋值运算符重载引发的思考(引用的功能) http://blog.csdn.net/yorkcai/article/details/8567441
- C++ 运算符的重载(转载自http://blog.csdn.net/insistgogo/article/details/6626952)
- C++的运算符重载 --http://blog.csdn.net/zgl_dm/article/details/1767201
- C++的运算符重载 http://blog.csdn.net/zgl_dm/article/details/1767201
- C++的运算符重载http://blog.csdn.net/zgl_dm/article/details/1767201
- 赋值运算符重载引发的思考(引用的强大功能)
- 赋值运算符重载引发的思考(引用的功能)
- C++_运算符重载 http://blog.csdn.net/insistgogo/article/details/6626952
- C++运算符重载http://blog.csdn.net/wangfengwf/article/details/11580653
- 重载operator ->的说明 http://blog.csdn.net/todototry/article/details/1481185
- 引用博客:http://blog.csdn.net/u012230055/article/details/64125268
- 重写、覆盖、重载、隐藏、多态几个概念的区别分析 http://blog.csdn.net/yukin_xue/article/details/7437742
- IBATIS的工作原理(1)(http://blog.csdn.net/chen861201/article/details/7614201)
- C++的内存管理(转载自:http://blog.csdn.net/bizhu12/article/details/6668834)
- Oracle+字符集的查看和修改(原文http://blog.csdn.net/tianlesoftware/article/details/4915223)
- ARM的几道题(转载http://blog.csdn.net/makethyme/article/details/1633381)
- dalvik虚拟机的工作流程(转http://blog.csdn.net/wsh604/article/details/7452726)
- 虚指针的用法(原出处//http://blog.csdn.net/haoel/article/details/1948051)
- HTML5 WebSocket 详解
- [LeetCode]Longest Palindromic Substring
- 第6周、项目2—建立链栈算法库
- 软件工程
- 2015-10-9 【项目2 - 建立链栈算法库】
- 赋值运算符重载引发的思考(引用的功能) http://blog.csdn.net/yorkcai/article/details/8567441
- 顺序栈
- 第四周项目三-单链表的应用(2)
- Spring如何通过注解方式注入静态属性
- IOS-8-Xcode6 使用MJRefresh报错:Too many arguments to function call, expected 0, have 3
- 第6周项目2--建立链栈算法库
- 第3周项目1 顺序表的基本运算(3)
- TestSSLServer
- 第6周 项目2-建立链栈算法库