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. popupwindow 与 输入法

    有时候popupwindow会被输入法覆盖, 有时候popupwindow会被输入法给顶上去. 而且这个问题还跟theme的windowFullscreen属性相关. 不过这些可以都不用管, 根据项目 ...

  2. WinForm 批量设置指定控件中的控件状态

    在开发中常遇到当点击某个按钮的时候,禁用文本框或按钮的的状态,以防止误操作,下面的代码是我已批量设置指定控件中的按钮状态的代码,同理可以延伸出很多操作. /// <summary> /// ...

  3. mac安装 配置 ant

    转自:http://blog.sina.com.cn/s/blog_877e9c3c0101qs87.html 1.下载ant 官网下载 http://ant.apache.org/bindownlo ...

  4. CSS基础(六):浮动深入

    参考了<CSS彻底设计研究>的文章,说的很不错,所以拿来做笔记. 浮动 在标准流中,一个块级元素在水平方向会自动伸展,直到包含它的元素边界:而在竖直方向和兄弟元素依次排列,不能并排.使用浮 ...

  5. SharePoint 2010中重置windows 活动目录(AD)域用户密码的WebPart(免费下载)

    由于SharePoint 2013推出不久,并非所有的企业都会升级到SharePoint 2013的,毕竟升级不是打打补丁这么简单,更多的企业还是使用Sharepoint 2010版本的,因此本人自行 ...

  6. 常用的sql语句(找不同位数,找重复)

    1.SQL找不同位数 select length(aae135),count(1) from ac01 group by  length(aae135) ; ————————————————————— ...

  7. 利用SVN工具下载OpenCore代码

    OpenCore原来使用的是CVS管理代码的.从09年起,更换用SVN管理代码,大家可以用TortoiseSVN软件下载代码,网址是:http://tortoisesvn.net/,安装后tortoi ...

  8. Elasticsearch及java客户端jest使用

    本文使用Github中的Elasticsearch-rtf,已经集成了众多的插件,例如必须使用的中文分词等,可以简单的通过配置来启用中文分词.本文主要分为以下几部分: 1.配置和启用中文分词: 2.定 ...

  9. codeforces B. Design Tutorial: Learn from Life

    题意:有一个电梯,每一个人都想乘电梯到达自己想要到达的楼层!从a层到b层的时间是|a-b|, 乘客上下电梯的时间忽略不计!问最少需要多少的时间....     这是一道神题啊,自己的思路不知不觉的就按 ...

  10. android自定义之 5.0 风格progressBar

    最近做项目,用到了ProgressBar ,就想到了要使用Android5.0 的效果,就随手实现了一下. 效果图: 大概的思路: 1. 圆圈通过Canvas去绘制 2.圆圈的动画通过Animator ...