class CMessage
{
private:
char * m_pMessage; public:
void showIt()const
{
cout << m_pMessage << endl;
}
//构造函数
CMessage(const char* text="Default message")
{
cout << "Constructor difinition" << endl; size_t length{strlen(text)+};
m_pMessage = new char[length+];
strcpy_s(m_pMessage,length+,text);
}
//复制构造函数
CMessage(const CMessage & aMess)
{
size_t len{strlen(aMess.m_pMessage)+};
this->m_pMessage = new char[len];
strcpy_s(m_pMessage,len,aMess.m_pMessage);
}
//重载赋值运算符
CMessage & operator=(const CMessage & aMess)
{
if (this!= &aMess)
{
delete[]m_pMessage;
size_t length{strlen(aMess.m_pMessage)+};
m_pMessage = new char[length];
strcpy_s(this->m_pMessage,length,aMess.m_pMessage);
}
return *this;
} //析构函数
~CMessage()
{
cout << "Destructor called" << endl;
delete[]m_pMessage;
}
}; int main()
{
CMessage motto1{"Amiss is as good as a mile"};
CMessage motto2; motto2 = motto1; motto2.showIt();
motto1.showIt(); return ;
}

复制构造函数:

当某个类动态的为数据成员分配空间,又利用按值传递给函数传递该类的对象,那么必须要实现复制构造函数

如:

  motto2 {motto1};

  CMessage & displayMessage(CMessage localMsg)
   {
    cout <<"the message is:----------------" << endl;
    localMsg.showIt();
    return *this;
   }

都会出现异常,如果没有实现复制构造函数,即两个对象的指针指向了同一块地址区域。

重载赋值运算符:

以现有的同类对象进行初始化类的对象,或者通过按值传递方式给函数传递对象,调用默认复制构造函数。

当赋值语句的左边和右边是同类类型的对象时,调用默认赋值运算符。

如:

  motto2 = motto1;

如果我们没有实现赋值运算符函数,编译器就会使用默认的赋值运算符函数,当为数据成员动态的分配内存,进行对象赋值,就会程序异常。

因为两个对象都有一个指向相同内存地址的指针。

分析赋值运算符函数:

CMessage & operator=(const CMessage & aMess)

{    if (this!= &aMess)

     {

      delete[]m_pMessage;

      size_t length{strlen(aMess.m_pMessage)+1};

        m_pMessage = new char[length];

      strcpy_s(this->m_pMessage,length,aMess.m_pMessage);

      }

  return *this;

}

delete[]m_pMessage; 删除分配给第一个对象的内存,重新分配足够的内存,以容纳第二个对象的字符串。

1、当 motto1 = motto1;会发生什么呢?

赋值运算符函数会释放 motto1 对象成员指向的内存

所以,if (this!= &aMess) 这条语句,是有必要的。

2、那么返回对象为什么?

motto1 = motto2=motto3;

这条语句的原型是:

    motto1.operator=(motto2.operator=(motto3));

可知 motto2.operator=(motto3) 的结果必须是对象才能作为 motto1.operator=()的参数。

3、那么返回引用为什么?

(motto1 = motto2)=motto3;

这条语句的原型是:

    (motto1.operator=(motto2)).operator=(motto3);

可知(motto1.operator=(motto2))的结果是个是个返回的临时对象,它是 rvalue ,编译器不允许使用 rvalue 调用函数成员。

而返回引用它是 lvalue。

重载赋值运算符 && 对象的更多相关文章

  1. 《挑战30天C++入门极限》C++运算符重载赋值运算符

        C++运算符重载赋值运算符 自定义类的赋值运算符重载函数的作用与内置赋值运算符的作用类似,但是要要注意的是,它与拷贝构造函数与析构函数一样,要注意深拷贝浅拷贝的问题,在没有深拷贝浅拷贝的情况下 ...

  2. mfc 重载赋值运算符

    重载赋值运算符= 一.重载运算符格式 返回类型 operator 运算符 (参数); 如: bool operator=(char*s); int operator>(char*s); bool ...

  3. 《剑指offer》第一题(重载赋值运算符)

    //重载赋值运算符 #include <iostream> #include <cstring> using namespace std; class CMystring { ...

  4. Python学习手册之内部方法、操作符重载和对象生命周期

    在上一篇文章中,我们介绍了 Python 的类和继承,现在我们介绍 Python 的内部方法.操作符重载和对象生命周期. 查看上一篇文章请点击:https://www.cnblogs.com/dust ...

  5. C++重载赋值运算符

    这是一道C++的面试题,下面在这篇博客中分析一下这个问题.先上题目: //题目:如下为类型CMyString的声明,请为该类型添加赋值运算符函数. class CMyString { public: ...

  6. Java基础语法04面向对象上-类-属性-方法-可变参数-重载-递归-对象数组

    类 面向对象是一种思想,一般指将事务的属性与方法抽出总结为模板(类/class),处理事务时通过类创建/new出对象由对象的功能/方法去完成所要计算处理的事情. 面向过程:POP:以过程,步骤为主,考 ...

  7. JAVA笔记2__类/封闭性/构造方法/方法的重载/匿名对象

    public class Main { public static void main(String[] args) { Chicken c1 = new Chicken(); Chicken c2 ...

  8. C++本质:类的赋值运算符=的重载,以及深拷贝和浅拷贝

    关键词:构造函数,浅拷贝,深拷贝,堆栈(stack),堆heap,赋值运算符摘要:    在面向对象程序设计中,对象间的相互拷贝和赋值是经常进行的操作.    如果对象在申明的同时马上进行的初始化操作 ...

  9. C++学习31 重载=(赋值运算符)

    和普通变量一样,对象之间也可以相互赋值.赋值运算符“=”可以用来将一个对象拷贝给另一个已经存在的对象.对象之间的赋值是将成员变量依次拷贝,而不是将整个对象的内存按位拷贝. 对象之间的赋值: #incl ...

随机推荐

  1. xsocks 64位平台下编译问题小记

    1.src/common/public.h uint32_t lpParameter 改为 void* lpParameter; 2.SocksMgr.cpp DWORD WINAPI CSocksM ...

  2. sql优化之(DMV)

    原文地址:http://technet.microsoft.com/zh-cn/library/bb838723.aspx Microsoft SQL Server 2005 提供了一些工具来监控数据 ...

  3. CISA 信息系统审计知识点 [第二章. IT治理和管理 ]

    第二章.  IT治理和管理 1.  IT治理.管理.安全和控制框架及标准.指南和实践 IT治理是董事会和执行管理层的职责. IT治理的关键因素:保持与业务的战略一致,引导业务价值的实现. IT治理关注 ...

  4. c++ 访问者模式(visitor pattern)

    概述: 我们去银行柜台办业务,一般情况下会开几个个人业务柜台的,你去其中任何一个柜台办理都是可以的.我们的访问者模式可以很好付诸在这个场景中:对于银行柜 台来说,他们是不用变化的,就是说今天和明天提供 ...

  5. Struts2知多少(1) Struts2 MVC架构

    模型视图控制器(Model View Controller)或MVC,MVC是俗称,是一种软件设计模式,用于开发Web应用程序.模型 - 视图 - 控制器模式是由以下三个部分组成: Model - 模 ...

  6. java模仿qq好友面板的布局(BoxLayout问题)

    .............. JLabel ll = new JLabel(dlg.getNameText() + ":" + dlg.getIPText(), ii[index] ...

  7. 【原创】C#搭建足球赛事资料库与预测平台(3) 基础数据表设计

            本博客所有文章分类的总目录:http://www.cnblogs.com/asxinyu/p/4288836.html 开源C#彩票数据资料库系列文章总目录:http://www.cn ...

  8. ruby -- 问题解决(四)编码错误导致无法显示(2)

    从数据库中取得数据显示时报 incompatible character encodings: GBK and ASCII-8BIT或 incompatible character encodings ...

  9. JavaScript TDD with Mocha

    开发现状 当新的版本快要发布的时候,大家都忙于加班,加紧修复BUG1.BUG2.我想这就是很多公司开发的现状. 为了不至于让上线的版本挂掉挂掉,少不了就是 人肉测试. 在一个项目中,我们会做许许多多各 ...

  10. Socket.IO 1.0 正式发布,快速可靠的实时引擎

    Socket.IO 是目前 Web 领域最火的实时引擎,用于实现基于事件的双向实时的通信.它适用于任何平台,浏览器或设备,专注于可靠性和速度.您可以将数据推送到客户端,并获得实时的计数,日志或图表. ...