首先定义类Person

class Person{
public:
  string name;
  Person()=default; //默认构造函数
Person(string nam):name(nam){}
void operator=(const Person& p){ //赋值构造函数
this->name=p.name;
}
};
Person a("xiaoming");
Person b;
cout<<b.name<<endl; //空
b=a;//执行赋值构造函数
cout<<b.name<<endl; //xiaoming

由上,赋值操作已完成,可为什么赋值构造函数还有个返回值

为什么有返回值?(初学者可能不理解b=a为什么会产生返回值)

首先b并不接收返回值(b=a让某些初学者误认为b接受返回值)

其实只要把b=a 看成是 a.operator=(b)就可以了

b=a的返回值就相当于a.operator=(b)这个函数的返回值

比如

我们来修改赋值构造函数返回值为一个具体的整数100

int operator=(const Person& p) {
this->name = p.name;
return ;
} cout<<+(b=a)<<endl; //

结果,(b=a)产生了一个临时变量100,然后这个临时变量和10相加得结果110,这个临时变量就是我们所谓的返回值

那返回值到底有什么用呢?

可以让对象进行链式操作

比如我们将返回值更改为这个对象的引用

Person& operator=(const Person& p) {
this->name = p.name;
return *this;
} Person& showName() {
cout<<this->name;
return *this;
} (b=a).showName(); //xiaoming

我们在给b赋值以后还能再让其还能再执行函数showName

那返回值是引用类型和非引用类型有区别吗?

区别当然大了

1.对一个对象进行两次连续的赋值操作

首先新建一个对象c

Person c("huanghuang");

1)赋值构造函数返回值是引用类型

(b=a)=c;
cout<<b.name<<endl; //huanghuang

2)赋值构造函数返回值不是引用类型


(b=a)=c;
cout<<b.name<<endl; //xiaoming

可以看到结果不同,究其原因,第2)种情况让系统拷贝了一份临时变量,因而是c给临时变量赋值,而非对象b

表一    结果对比表

返回值类型           (b=a)执行后产生的结果

Person&                       b的引用

Person             b的一份拷贝(临时变量)

扩展阅读:

临时变量又叫做右值,左值就是非临时变量

详细解释:( https://blog.csdn.net/thisinnocence/article/details/23883483  https://www.ibm.com/developerworks/cn/aix/library/1307_lisl_c11/  https://blog.csdn.net/zhangsj1007/article/details/79940370【三篇关于左值右值的讲解】)

粗糙解释:就是在执行某段代码中间产生的临时变量,这个临时变量在执行完这段代码后就会被析构,除非你引用了这个临时变量。

//如果返回值类型不为引用  产生了临时变量  我们引用这个临时变量

Person&& d=b=a;

Person&用于引用一个已经被定义好的Person对象

Person&&则是用于引用一个临时的Person对象(认领这块无主之地)

2.将一个对象连续赋值给两个对象

即a=b=c

首先我们增加一个拷贝构造函数 再给赋值构造函数增加一个输出

Person(const Person&p) { cout<<"copy constructor"<<endl; }
Person& operator=(const Person& p) {
cout << "copy assignment constructor" << endl;
this->name = p.name;
return *this;
} a=b=c; 1)赋值构造函数返回值为引用类型
copy assignment constructor
copy assignment constructor 2)赋值构造函数返回值为非引用类型
copy assignment constructor
copy constructor
copy assignment constructor
copy constructor

我们看到赋值构造函数返回值为非引用类型时,导致系统为其拷贝生成两个临时变量

虽然最后达到的目的一致,但是增加了内存开支

综上,复制构造函数的返回值为引用类型比较好,在给多个对象赋值时,可以节省内存开支,在进行链式操作时,不但可以节省内存开支,还可以对其进行修改性操作

C++ 赋值构造函数的返回值到底有什么用?且返回值是否为引用类型有什么区别吗?的更多相关文章

  1. C++ 为什么拷贝构造函数参数必须为引用?赋值构造函数参数也必须为引用吗?

    之前写拷贝构造函数的时候,以为参数为引用,不为值传递,仅仅是为了减少一次内存拷贝.然而今天看到一篇文章发现自己对拷贝构造的参数理解有误. 参数为引用,不为值传递是为了防止拷贝构造函数的无限递归,最终导 ...

  2. c++赋值构造函数为什么返回引用类型?

    目录 0 前言 1 内置类型 2 自定义类型 3 结论 4 源码 0. 前言 c++默认赋值构造函数的返回值是引用类型,c++赋值运算符=的本意是返回左值的引用,我们重载赋值构造函数的时候,返回值是否 ...

  3. Java的Object.hashCode()的返回值到底是不是对象内存地址?

    关于这个问题,查阅了网上的资料,发现证明过程太繁琐,这里我用了反证法. java.lang.Object.hashCode()的返回值到底是不是对象内存地址? hashCode契约 说到这个问题,大家 ...

  4. out.println(session.getLastAccessedTime());的返回值到底是毛线意思???

    out.println(session.getLastAccessedTime());这个语句是输出最后一次成功获取session对象Attribute值的一个指令, 他的返回值是一个long型数据, ...

  5. (copy)赋值构造函数的4种调用时机or方法

    第一种调用方法: demo #include <iostream> using namespace std; class Text { public: Text() // 无参数构造函数 ...

  6. c++类大四个默认函数-构造函数 析构函数 拷贝构造函数 赋值构造函数

    每个类只有一个析构函数和一个赋值函数,但可以有多个构造函数(包含一个拷贝构造函数,其它的称为普通构造函数).对于任意一个类A,如果不编写上述函数,C++编译器将自动为A 产生四个缺省的函数,例如: A ...

  7. C++类中函数(构造函数、析构函数、拷贝构造函数、赋值构造函数)

    [1]为什么空类可以创建对象呢? 示例代码如下: #include <iostream> using namespace std; class Empty { }; void main() ...

  8. 调试台自动多出现一个'&#65279;' ,我 用uploadify上传图片时,在给页面写入一个返回值为图片名称的变量的值的时候值的前面始终多出现一个'&#65279;'

    对你有助请点赞,请顶,不好请踩------送人玫瑰,手留余香! 15:54 2016/3/12用uploadify上传图片时,在给页面写入一个返回值为图片名称的变量的值的时候值的前面始终多出现一个' ...

  9. Android For JNI(三)——C的指针,指针变量,指针常见错误,值传递,引用传递,返回多个值

    Android For JNI(三)--C的指针,指针变量,指针常见错误,值传递,引用传递,返回多个值 C中比较难的这一块,大概就是指针了,所以大家还是多翻阅一下资料,当然,如果只是想了解一下,看本篇 ...

随机推荐

  1. H5测试与PC端测试不同的点

    1.通过H5网页(非手机的返回功能)的返回功能可以返回,不会出现无法返回的情况. 2.横屏竖屏相互切换,能自适应,并且布局不会乱掉: 3.为能在不同分辨率的手机上能更好的展示,建议采用响应式设计(如: ...

  2. 安装Visual C++ 6.0后报错:应用程序无法正常启动(0xc0000142)

    最近在安装Visual C++ 6.0时,本来想用个中文版的,结果刚安装好就报了这个错误 百度后发现是由于汉化后的Visual C++ 6.0与win10不兼容造成的 解决办法就是替换程序,把中文版的 ...

  3. python 函数split()

    函数:split() Python中有split()和os.path.split()两个函数,具体作用如下:split():拆分字符串.通过指定分隔符对字符串进行切片,并返回分割后的字符串列表(lis ...

  4. [Caffe]Win10+VS2015+CUDA8.0+cudnn5.1环境配置

    百度:win10 caffe vs2015 编译caffe.sln工程参见->这里 caffe训练参见->这里 参见->这里 Windows+VS2013爆详细Caffe编译安装教程

  5. XVII Open Cup named after E.V. Pankratiev. GP of Tatarstan

    A. Arithmetic Derivative 形如$p^p(p是质数)$的数的比值为$1$,用$k$个这种数相乘得到的数的比值为$k$,爆搜即可. #include<cstdio> # ...

  6. flask之入门

    本篇导航: Flask介绍 简单使用 排错 小结 一. Flask介绍 Flask是一个基于Python开发并且依赖jinja2模板和Werkzeug WSGI服务的一个微型框架,对于Werkzeug ...

  7. (88)Wangdao.com第二十一天_JavaScript 元素节点Element 节点

    Element 节点 (元素节点) 是一组对象 对应网页的 HTML 元素 每一个 HTML 元素,在 DOM 树上都会转化成一个 Element 节点对象(以下简称元素节点) 所有元素节点的 nod ...

  8. MySQL自动备份shell脚本

    在数据库的日常维护工作中,除了保证业务的正常运行以外,就是要对数据库进行备份,以免造成数据库的丢失,从而给企业带来重大经济损失.通常备份可以按照备份时数据库状态分为热备和冷备,按照备份数据库文件的大小 ...

  9. Python基础之容器1----字符串和列表

    一.编码: 1.编码只是梳理 2.编码涉及的函数: 3.实例: 字符串内存图 二.字符串 1.定义:由一系列字符组成的不可变序列容器,存储的是字符的编码值. 不可变:指字符串一旦定义,其内存地址就已经 ...

  10. VIm快捷操作

    vim快捷操作 移动 行级移动 $ 行尾 0 行头 段级移动 { 段首 } 段尾 屏幕级别 L: 屏幕尾部 H: 屏幕头部 文档级别 G: 文档尾部 1G:头部 nG:文档n行 删除 dd: 删除当前 ...