【转】C++的赋值构造函数(赋值运算符重载)

当一个类的对象向该类的另一个对象赋值时,就会用到该类的赋值构造函数。

当没有重载赋值构造函数(赋值运算符)时,通过默认赋值构造函数来进行赋值操作

注意:这里a,b对象是已经存在的,是用a对象来赋值给b的。

赋值运算符的重载声明如下:

通常大家会对拷贝构造函数和赋值构造函数混淆,这里仔细比较两者的区别:

1)拷贝构造函数是一个对象初始化一块内存区域,这块内存就是新对象的内存区,而赋值构造函数时对于一个已经被初始化的对象来进行赋值操作。

2)实现不一样,拷贝构造函数首先是一个构造函数,它调用时候是通过参数的对象初始化产生一个新对象。赋值构造函数是把一个新的对象赋值给一个原有的对象。

举例:

结果:

说明:

1、参数

一般地,赋值运算符重载函数的参数是函数所在类的const类型的引用,加const是因为:

(1)我们不希望在这个函数中对用来进行赋值的”原版”做任何修改。

(2)加上const,对于const的和非const的实参,函数都能接受;如果不加,就只能接受非const的实参。

用引用是因为:

这样可以避免在函数调用时对实参的一次拷贝,提高了效率。

注意:上面的规定都不是强制的,可以不加const,也可以没有引用。

2、返回值

一般地,返回值是被赋值者的引用,即*this(如上面例1),原因是:

(1)这样在函数返回时避免一次拷贝,提高了效率。

(2)更重要的,这样可以实现连续赋值,即类似a=b=c这样。如果不是返回引用而是返回值类型,那么,执行a=b时,调用赋值运算符重载函数,在函数返回时,由于返回的是值类型,所以要对return后边的”东西”进行一次拷贝,得到一个未命名的副本(有些资料上称之为”匿名对象”),然后将这个副本返回,而这个副本是右值,所以,执行a=b后,得到的是一个右值,再执行=c就会出错。

注意:这也不是强制的,我们甚至可以将函数返回值声明为void,然后什么也不返回,只不过这样就不能够连续赋值了

3、赋值运算符重载函数不能被继承

因为相较于基类,派生类往往要添加一些自己的数据成员和成员函数,如果允许派生类继承积累的赋值运算符重载函数,那么,在派生类不提供自己的赋值运算符重载函数时,就只能调用基类的,但基类版本只能处理基类的数据成员,在这种情况下,派生类自己的数据成员怎么办?所以,C++规定,赋值运算符重载函数不能被继承。

4、赋值运算符重载函数要避免自赋值

对于赋值运算符重载函数,我们要避免自赋值(即自己给自己赋值)的发生,一般地,我们通过比较赋值者与被赋值者的地址是否相同来判断两者是否是同一对象(如例中的if(this != &str)一句)。避免自赋值的意义是:

(1)提高效率,显然,自己给自己赋值完全是毫无意义的无用功,特别地,对于基类数据成员间的赋值,还会调用基类的赋值运算符重载函数,开销是很大的。如果我们一旦判定是自赋值,就立即return *this,会避免对其它函数的调用。

(2)如果类的数据成员中含有指针,自赋值有时会导致灾难性的后果。对于指针间的赋值(注意这里指的是指针所指内容间的赋值,这里假设用_p给p赋值),先要将p所指向的空间delete掉(为什么要这么做呢?因为指针p所指的空间通常是new来的,如果在为p重新分配空间前没有将p原来的空间delete掉,会造成内存泄露),然后再为p重新分配空间,将_p所指的内容拷贝到p所指的空间。如果是自赋值,那么p和_p是同一指针,在赋值操作前对p的delete操作,将导致p所指的数据同时被销毁。那么重新赋值时,拿什么来赋?

所以,对于赋值运算符重载函数,一定要先检查是否是自赋值,如果是,直接return *this。

转载自:

Original: https://www.cnblogs.com/codingmengmeng/p/14116916.html
Author: 阿玛尼迪迪
Title: 【转】C++的赋值构造函数(赋值运算符重载)

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/535172/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • C++实现图的遍历和最短路径

    摘自:https://blog.csdn.net/qq_45694646/article/details/106764026 C++实现图的基本操作 数据结构之图(存储,遍历,最短…

    C++ 2023年5月29日
    076
  • 无废话–Mac OS, VS Code 搭建c/c++基本开发环境

    无废话,直接上步骤。 1) 安装 xcode。 打开App Store,搜索xcode,进行下载安装。 2)执行命令: xcode-select –install 安装…

    C++ 2023年5月29日
    072
  • C++ mutable的用法

    mutalbe的中文意思是”可变的,易变的”,跟constant(既C++中的const)是反义词。 在C++中,mutable也是为了突破const的限制…

    C++ 2023年5月29日
    058
  • Dev-C++

    官网: http://orwelldevcpp.blogspot.com/ 最新版本: Version 5.11 – 27 April 2015 下载链接: https…

    C++ 2023年5月29日
    072
  • 《Accelerated C++》学习笔记(1)——学习资料

    最近找到一本C++的书籍,英文名字《 Accelerated C++: Practical Programming by Example》,作者 Andrew Koenig, Ba…

    C++ 2023年5月29日
    076
  • c++实践课(上课用)

    源程序: //编写一个程序,将从键盘输入的n个字符串保存在一个一维数组A中。在输入字符串之前,先输入n的值。//要求,数组A需要动态申请空间,程序运行结束前再释放掉。//再输出n字…

    C++ 2023年5月29日
    058
  • c++如何遍历删除map/vector里面的元素

    新技能Get! 对于c++里面的容器, 我们可以使用iterator进行方便的遍历. 但是当我们通过iterator对vector/map等进行修改时, 我们就要小心了, 因为操作…

    C++ 2023年5月29日
    0100
  • 使用Visual Leak Detector for Visual C++ 捕捉内存泄露

    1、下载vlc 2、创建应用并配置 c/c++ -> General -> Additional Include Directories = C:\Program Fi…

    C++ 2023年5月29日
    064
  • C++:继承访问属性(public/protected/private)

    我不去想是否能够成功 既然选择了远方 便只顾风雨兼程 Original: https://www.cnblogs.com/adylee/p/11432895.htmlAuthor:…

    C++ 2023年5月29日
    082
  • C++常用的设计模式

    单例模式: 单例模式:确保一个类只有一个实例,并且这个实例化向整个系统提供 (例如只有一台打印机,可以有多个打印任务队列,但是只能有一个正在打印)。单例模式又分为(饿汉模式,懒汉模…

    C++ 2023年5月29日
    060
  • std::get<C++11多线程库~线程间共享数据>(09):共享数据带来的问题(1)

    1 #include 2 3 /* 4 * 话题1:线程间共享数据 5 * a. 共享数据带来的问题 6 * b. 使用互斥量保护数据 7 * c. 数据保护的替代方案 8 * 9…

    C++ 2023年5月29日
    064
  • 关于C++ const 的全面总结

    C++中的const关键字的用法非常灵活,而使用const将大大改善程序的健壮性,本人根据各方面查到的资料进行总结如下,期望对朋友们有所帮助。 Const 是C++中常用的类型修饰…

    C++ 2023年5月29日
    055
  • c++为什么要面向对象?

    前言 c和c++的区别是什么?不可置否,最重要的就是c++的编程思想是面向对象,而c的编程思想是面向过程,这是它们的本质区别,如果你在使用c++编程时使用的还是面向过程的编程思想,…

    C++ 2023年5月29日
    068
  • C++接口设计和代码重构

    讲了接口设计, 文档(doxygen),测试等方面。对于从头编写基础库, 或者没有基础库开发经验并且需要短期内上手, 有一定实际参考价值。 所谓Mikado Method方法是用来…

    C++ 2023年5月29日
    064
  • C++ 11 关键字:thread_local(转)

    thread_local 是 C++ 11 新引入的一种存储类型,它会影响变量的存储周期。 C++ 中有 4 种存储周期: 有且只有 thread_local 关键字修饰的变量具有…

    C++ 2023年5月29日
    051
  • WIN部分程序调用VS C++库导致提示报错R6034解决方法

    最近电脑上的部分软件运行的时候有时候会报错R6034,猜测可能是软件安装冲突导致 可能是因为软件在调用VS C++runtime error库的dll文件的时候找不到或者找到了错误…

    C++ 2023年5月29日
    091
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球