c/c++语言开发共享C++重载赋值运算符

[TOC] 一、为什么要重载赋值运算符 ​ 在前面的内容中讲解 “拷贝构造函数调用的时机” 时说明了初始化和赋值的区别:在定义的同时进行赋值叫做 ,定义完成以后再赋值(不管在定义的时候有没有赋值)就叫做 。初始化只能有一次,赋值可以有多次。 ​ 当以拷贝的方式初始化一个对象时,会调用拷贝构造函数;当 …

目录

一、为什么要重载赋值运算符

​ 在前面的内容中讲解 时说明了初始化和赋值的区别:在定义的同时进行赋值叫做初始化,定义完成以后再赋值(不管在定义的时候有没有赋值)就叫做赋值。初始化只能有一次,赋值可以有多次。

​ 当以拷贝的方式初始化一个对象时,会调用拷贝构造函数;当给一个对象赋值时,会调用重载过的赋值运算符。即使没有显式的重载赋值运算符,编译器也会以默认地方式重载它。默认重载的赋值运算符功能很简单,就是将原有对象的所有成员变量一一赋值给新对象,这和默认拷贝构造函数的类似。看下面的代码:

#include <iostream> #include<string> using namespace std;  class people { public:     people(string name = "", int* ptr =null);  // 普通构造函数,     people(const people &peo);   //显示声明拷贝构造函数     ~people();     void display();     void setage(int age); private:     string m_name;     int* mp_age;  };   people::people(string name, int* ptr) {     m_name = name;     mp_age = ptr; }  people::people(const people &peo) {     this->m_name = peo.m_name;     this->mp_age = new int(*peo.mp_age);  //重新申请一块内存来存放 age,避免两个对象使用同一块内存 }  people::~people() {     delete mp_age;  // 不重载赋值运算符时多次释放内存会导致崩溃。     mp_age = null; }   void people::display() {     cout << m_name <<" is age "<< *mp_age << endl; }  void people::setage(int age) {     *mp_age = age; }  int main() {     int* ptr = new int(10);     string name = "xiao ming";     people people1 = people(name, ptr);     people people2;      people2 = people1;  //不重载赋值运算符      people1.display();     people2.display();      people1.setage(15);  // 修改 people1 age          people1.display();     people2.display();      return 0; }  /* 输出: xiao ming is age 10 xiao ming is age 10 xiao ming is age 15 xiao ming is age 15   //修改 people1 age 之后 people2 age 也被修改了,而且调用析构函数的时候回重复释放内存导致崩溃。   */ 

​ 看上面的例子修改 people1 age 之后 people2 age 也被修改了,这是因为mp_age 是一个指针,里面存放的是指向存储 age 内容的地址,不重载赋值运算符时,使用默认的赋值运算符时这是把 people1的 mp_age指针里存放的地址赋值给了people2的mp_age指针导致两个指针指向了同一块内存空间,这时候默认赋值运算符的不足就满足不了实际的需求了,需要重载赋值运算符。

二、重载赋值运算符

​ 对于简单的类,默认的赋值运算符一般就够用了,我们也没有必要再显式地重载它。但是当类持有其它资源时,例如动态分配的内存、打开的文件、指向其他数据的指针、网络连接等,默认的赋值运算符就不能处理了,我们必须显式地重载它,这样才能将原有对象的所有数据都赋值给新对象。下面我们重载赋值运算符来实现默认赋值运算符不能实现的功能。

#include <iostream> #include<string> using namespace std;  class people { public:     people(string name = "", int* ptr =null);  // 普通构造函数,     people(const people &peo);   //显示声明拷贝构造函数     ~people();     people& operator=(const people &peo);  // 重装赋值运算符     void display();     void setage(int age); private:     string m_name;     int* mp_age;  };  people::people(string name, int* ptr) {     m_name = name;     mp_age = ptr; }  people::people(const people &peo) {     this->m_name = peo.m_name;     this->mp_age = new int(*peo.mp_age);  //重新申请一块内存来存放 age,避免两个对象使用同一块内存 }  people::~people() {     //释放内存,防止内存泄漏     delete mp_age;       mp_age = null; }  // 重装赋值运算符 people& people::operator=(const people &peo) {     if (this != &peo)      {         this->m_name = peo.m_name;         if (null != this->mp_age)         {             *this->mp_age = *peo.mp_age;         }         else         {             this->mp_age = new int(*peo.mp_age);         }     }     return *this; }  void people::display() {     cout << m_name <<" is age "<< *mp_age << endl; }  void people::setage(int age) {     *mp_age = age; }  int main() {     int* ptr = new int(10);     string name = "xiao ming";     people people1 = people(name, ptr);     people people2;      people2 = people1;      people1.display();     people2.display();      people1.setage(15);  // 修改 people1 age          people1.display();     people2.display();      return 0; } /* 输出: xiao ming is age 10 xiao ming is age 10 xiao ming is age 15 xiao ming is age 10  //修改 people1 age 之后 people2 age 没有被修改,   */  
关于上面代码的几点说明:
  1. operator=() 的返回值类型为people &,这样不但能够避免在返回数据时调用拷贝构造函数,还能够达到连续赋值的目的,这样的语句就是连续赋值:people1 = people2 = people3;

  2. if( this != &arr)`语句的作用是「判断是否是给同一个对象赋值」:如果是,那就什么也不做;如果不是,那就将原有对象的所有成员变量一一赋值给新对象,并为新对象重新分配内存。

  3. 赋值运算符重载函数除了能有对象引用这样的参数之外,也能有其它参数。但是其它参数必须给出默认值,例如people& operator=(const people &peo, int a = 100);

  4. operator=() 的形参类型为const people &,这样不但能够避免在传参时调用拷贝构造函数,还能够同时接收 const 类型和非 const 类型的实参.

www.ctvol.com true Article c/c++语言开发共享C++重载赋值运算符

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/c-cdevelopment/605058.html

(0)
上一篇 2021年5月13日 上午2:42
下一篇 2021年5月13日 上午2:46

精彩推荐