代码出自剑指offer,自己做了详细的注释,代码如下:

#include<cstring>
#include<cstdio>
#include<iostream>using namespace std;class CMyString
{
public:CMyString(const char* pData = nullptr);//构造函数CMyString(const CMyString& str);//构造函数~CMyString(void);//析构函数CMyString& operator = (const CMyString& str);//算术符重载void Print();private:char* m_pData;
};CMyString::CMyString(const  char *pData)//传一个字符串进去
{if (pData == nullptr){m_pData = new char[1]; //开辟空间大小为1m_pData[0] = '\0';}else{int length = strlen(pData);m_pData = new char[length + 1];strcpy_s(m_pData, length + 1, pData);//因为要考虑\0占据一个单位,所以是length + 1,这里是把pData赋值给m_pData的意思}
}CMyString::CMyString(const CMyString &str)//传一个对象进去
{int length = strlen(str.m_pData);m_pData = new char[length + 1];strcpy_s(m_pData, length + 1, str.m_pData);
}CMyString::~CMyString()//析构函数
{delete[] m_pData;
}// 重载 + 运算符,用于把两个 Box 对象相加
//Box                 operator + (const Box& b)
CMyString& CMyString::operator = (const CMyString& str)//算术符号重载,返回类型是对象的引用,::operator =表示重载函数在类外面被调用,(const CMyString& str)表示被重载的=右侧的的数据类型是什么
{if (&str != this)//这个意思是,如果当前对象和原有的对象不是同一个的话{CMyString strTemp(str);char* pTemp = strTemp.m_pData;strTemp.m_pData = m_pData;m_pData = pTemp;}//假设我们的算术重载最终是想要执行CMyString xxx=y这样的操作。//注意,这里离开if以后,strTemp会被自动析构,而pTemp也会被删除,因为它们都是局部变量//这里之所以这么操作,是因为,如果直接把str赋值给this的话,可能需要为m_pData开辟的空间不够了,这个时候//m_pData就会得到一个空指针,最终在cout输出空指针时就会挂掉。//挂掉只是其次,原来的CMyString数据可能也会被毁掉,因为可能执行了CMyString xxx=NUll这样的语句效果//为了不毁掉原来的CMyString xxx中的内容,先把str的内容拷贝到一个临时的对象CMyString strTemp中//那么此时,即使空间不够程序挂掉,原来的CMyString xxx的数据也不会被毁掉。//也就是说空指针进行赋值是不会导致崩溃的,但是输出空指针是会导致程序崩溃的cout <<this << endl;return *this;//返回当前对象的引用,如果是return this,那么就返回当前对象的地址
}//这里之所以是返回*this,是因为重载本身就是在处理对象,或者说,是在调整对象的属性,所以调整前和调整后,都是对象进,对象出。// ====================测试代码====================
void CMyString::Print()
{printf("%s", m_pData);
}void Test1()
{printf("Test1 begins:\n");const  char* text = "Hello world"; //不可更改的字符串指针CMyString str1(text);//利用构造函数进行初始化CMyString str2;str2 = str1;//对象赋值printf("The expected result is: %s.\n", text);printf("The actual result is: ");str2.Print();printf(".\n");
}// 赋值给自己
void Test2()
{printf("Test2 begins:\n");const char* text = "Hello world";CMyString str1(text);str1 = str1;printf("The expected result is: %s.\n", text);printf("The actual result is: ");str1.Print();printf(".\n");
}// 连续赋值
void Test3()
{printf("Test3 begins:\n");const char* text = "Hello world";CMyString str1(text);CMyString str2, str3;str3 = str2 = str1;printf("The expected result is: %s.\n", text);printf("The actual result is: ");str2.Print();printf(".\n");printf("The expected result is: %s.\n", text);printf("The actual result is: ");str3.Print();printf(".\n");
}int main(int argc, char* argv[])
{Test1();Test2();Test3();cin.get();cin.get();return 0;
}

上图是代码中的异常安全处理部分的数据流图

关于空指针导致崩溃问题可以参考点击打开链接

01_AssignmentOperator详细解释相关推荐

  1. Python精讲Numpy基础,大牛笔记详细解释

    https://www.toutiao.com/a6664936105076326920/ 总认为Numpy是渣渣,直到深入接触以后才知道功能这么强大.堪比Matlab啊.果然是人生苦短,我用Pyth ...

  2. UIApplication sharedApplication详细解释-IOS

    UIApplication sharedApplication详细解释-IOS 分类: iOS开发2012-07-27 10:25 10287人阅读 评论(2) 收藏 举报 applicationui ...

  3. MongoDB:详细解释mongodb的高级操作,聚合和游标

    前几天总结了mongodb的安装入门.详细解释了增删改查的基本操作,今天再来总结下mongodb更高级的操作,聚合和游标. 一.聚合,mongodb的聚合操作一般分为四种情景,分别是:count.di ...

  4. PySide2 基础入门-创建实例窗口(详细解释)

    PySide2 基础入门-创建实例窗口(详细解释) python 3.7 / Pyside2 (如果使用pyQt5,将Pyside2 直接替换PyQt5即可)首先我们在Qt Designer中画好界面 ...

  5. Python之pandas:pandas.set_option函数的参数详细解释

    Python之pandas:pandas.set_option函数的参数详细解释 目录 pandas.set_option函数的参数解释 函数API:pandas.set_option pandas. ...

  6. linux中useradd的文件路径,linux的useradd命令详细解释

    Linux中的useradd命令顾名思义就是添加用户的命令.下面由学习啦小编为大家整理了Linux的useradd命令的详细解释的相关知识,希望对大家有帮助! linux的useradd命令的详细解释 ...

  7. 英语中的介词详细解释

    英语中的介词详细解释 xixi2015-01-05 10:02:58 转载于:https://www.cnblogs.com/lyhabctranslate/p/4202991.html

  8. ios学习--TableView详细解释

    2019独角兽企业重金招聘Python工程师标准>>> ios学习--TableView详细解释 分类: ios Object-C 2012-05-17 08:48  1714人阅读 ...

  9. theano中的Rop和Lop的详细解释

    #------------------------------------------序------------------------------------------------------- ...

最新文章

  1. x-manager 管理 kvm虚拟机
  2. 编译安装_在Centos7下编译安装新版本内核
  3. rxjs 里的map operator
  4. OpenCV cvLine
  5. layui中table监听单元格_最全总结 | 聊聊 Python 办公自动化之 PPT(中)
  6. Python语言学习笔记
  7. RegExp 构造函数
  8. CSS text-decoration 属性
  9. 如何为SharePoint添加一个简单地SMTP邮件发送服务器?
  10. GMS匹配算法论文、源码笔记
  11. Ubuntu 用vsftpd 配置FTP服务器教程详解
  12. 回到顶部的几种实现方法
  13. sql计算字段中字数的个数
  14. 蚂蚁金服推出 BaaS 平台:巨头角逐之下,商业机会正快速来临
  15. 想在公众号上做一个测试软件,公众号测试新功能想要扭转乾坤?
  16. 群晖、黑群晖安装emby很慢,或者卡0%的解决办法,请收藏
  17. [1.24] T3-人品问题
  18. Zookeeper集群一致性原理(强一致性)
  19. PMP报考一定要报培训班吗?
  20. 墨魂服务器维修,2013年10月22日定期维护公告

热门文章

  1. 软件工程启程篇章:C#和四则运算生成与运算
  2. Session的实现与存储
  3. (原) ora-12705 cannot access nls data files or invalid environment specified
  4. MOCTF-Web-访问限制
  5. 网桥如何把信号传给服务器,无线网桥传输的三种传输方式
  6. 学习响应式BootStrap来写融职教育网站,Bootsrtap第二天
  7. Node.js 安装及配置
  8. vue的props实现父组件变化子组件一起变化
  9. 每天定时查询CSDN博客访问量,并通过echarts进行展示
  10. Android:JAVA使用HDF5存储