赋值运算符重载

对于非内部类对象的赋值,会存在一个默认的赋值运算符重载函数。

如下面的代码中,c2=c1这句中调用了类A的默认的赋值运算符重载函数,实现了c2.real=c1.real;  c2.image=c1.image;

class A{
  private:
      int real;
      int image;
  public:
      A(int r,int i)
     {
          real=r;
          image=i;
     }
};

int main()
{
     A c1(1,2);
     A c2(0,0);
     c2=c1;
}
  • 那么赋值运算符重载函数 显式定义的时机是什么?
    当类成员变量中有动态分配的存储空间时,需要显式定义。否则会出现与浅拷贝同样的问题,c1给c2赋值后,c1和c2中的指针指向同一个内存空间,析构时,同一个空间被析构两次,出现运行错误。
  • 赋值运算符重载函数与拷贝构造函数的不同之处?(例子如下代码)
    1)赋值运算符重载函数需要先释放对象自身空间原来的内容,再根据赋值对象c1的动态申请的内存空间大小,给c2动态申请同样大小的空间,再进行赋值;
        拷贝构造函数只需要直接根据c1中的动态申请的内存大小,给c2动态申请同样大小的空间,进行赋值,不需要对c2先释放,因为c2还没初始化呢,拷贝构造函数是在c2初始化时调用的,A c2=c1;
    2)调用时机不同,拷贝构造函数在初始化时调用,赋值运算只在赋值时调用。

    拷贝构造函数和赋值运算符重载:

    class A{
    private:
        char *name;
        char *namep;
    public:
        A(A& a1)
        {
            if(a1.name)
            {
                 name=new char[strlen(a1.name)+1];
                 strcpy(name,a1.name);
            }
            if(a1.namep)
            {
                 namep=new char[strlen(a1.namep)+1];
                 strcpy(namep,a1.namep);
            }
        }
        A &operator =(A &a1)
        {
             if(name)  delete []name;
             if(namep) delete []namep;
             if(a1.name)
             {
                  name=new char[strlen(a1.name)+1];
                  strcpy(name,a1.name);
             }
             else
                 name=NULL;
             if(a1.namep)
             {
                   namep=new char[strlen(a1.namep)+1];
                   strcpy(namep,a1.namep);
             }
             else
                 namep=NULL;
    
             return *this;
        }
    };                                    
  • 赋值运算符重载函数的形参讨论;
    赋值运算符的形参通常是本类对象的引用,因为对象的占用内存可能较大,使用本类对象引用,省去了临时对象所需的栈空间。同时不调用拷贝构造函数,也省去了拷贝的时间。
    当然为了避免形参的值被改变,加const限定引用。因此形参为本类对象的 常引用。const A& a1;
  • 赋值运算符重载函数返回值讨论:
    返回值可以是:void型返回,本类对象返回,本类对象的引用返回;
    1)返回void型。赋值能够正常进行,但是因为没有返回值,那么赋值表达式不能连续赋值。
    2)返回本类对象。会在返回时创建临时对象,调用拷贝构造函数初始化临时对象,函数结束后,临时对象会被析构;
    3)返回本类对象的引用。不需要初始化内存临时对象,返回值是对象本身,即*this。
时间: 2024-10-24 23:57:05

赋值运算符重载的相关文章

第五篇:明确拒绝不想编译器自动生成的拷贝构造函数和赋值运算符重载函数

前言 如果你不想要编译器帮你自动生成的拷贝机制 (参考前文),那么你应当明确的拒绝. 如何拒绝?这便是本文要解决的主要问题. 问题描述 当你定义了一个类,而这个类中各对象之间也是封装的 - 禁止同类对象之间的相互赋值以及复制,那么你需要屏蔽掉编译器帮你生成的拷贝构造函数以及赋值运算符. 在许多代码中,会看到通过将拷贝构造函数和赋值运算符重载函数声明为私有且不予实现来实现这个功能.然而,这不是最科学的做法. 因为这没有做到真正的屏蔽:你在自己的成员函数中,或者友元函数中仍然可以调用这两个私有函数,

明确拒绝不想编译器自动生成的拷贝构造函数和赋值运算符重载函数

前言 如果你不想要编译器帮你自动生成的拷贝机制 (参考前文),那么你应当明确的拒绝. 如何拒绝?这便是本文要解决的主要问题. 问题描述 当你定义了一个类,而这个类中各对象之间也是封装的 - 禁止同类对象之间的相互赋值以及复制,那么你需要屏蔽掉编译器帮你生成的拷贝构造函数以及赋值运算符. 在许多代码中,会看到通过将拷贝构造函数和赋值运算符重载函数声明为私有且不予实现来实现这个功能.然而,这不是最科学的做法. 因为这没有做到真正的屏蔽:你在自己的成员函数中,或者友元函数中仍然可以调用这两个私有函数,

拷贝构造函数和赋值运算符重载的区别

拷贝构造函数是用一个已存在的对象去构造一个不存在的对象(拷贝构造函数毕竟还是构造函数嘛),也就是初始化一个对象.而赋值运算符重载函数是用一个存在的对象去给另一个已存在并初始化过(即已经过构造函数的初始化了)的对象进行赋值. 它们定义上的区别,楼上的已经说过了. 比如:String s1("hello"),s2=s1;//拷贝构造函数Sring s1("hello"),s2;s1=s2;//赋值运算符重载以下情况都会调用拷贝构造函数:1.一个对象以值传递的方式传入函数

C++ Primer 学习笔记_27_操作符重载与转换(2)--++/--运算符重载、!运算符重载、赋值运算符重载 、String类([]、 +、 += 运算符重载)、>>和<<运算符重载

C++ Primer 学习笔记_27_操作符重载与转换(2)--++/--运算符重载.!运算符重载.赋值运算符重载 .String类([]. +. += 运算符重载).>>和<<运算符重载 一.++/--运算符重载 1.前置++运算符重载 成员函数的方式重载,原型为: 函数类型 & operator++(); 友元函数的方式重载,原型为: friend 函数类型 & operator++(类类型 &); 2.后置++运算符重载 成员函数的方式重载,原型为:

拷贝构造函数与赋值运算符重载函数要点

拷贝构造函数 一个小例子 最近在<剑指Offer>上看到了一道题(程序如下),要求我们分析编译运行的结果,并提供3个选项: A. 编译错误: B. 编译成功,运行时程序崩溃:C. 编译运行正常,输出10. 1 #include <iostream> 2 using namespace std; 3 4 class A 5 { 6 private: 7 int value; 8 9 public: 10 A(int n) { value = n; } 11 A(A other) {

赋值运算符重载和拷贝构造函数 AND 浅拷贝与深拷贝

赋值运算符重载: 是用一个已经存在的对象去给另一个已经存在并初始化(调用过构造函数)的对象进行赋值. 拷贝构造函数:其实本质还是构造函数,用一个已存在的对象去构造一个原先不存在的对象. string a("hello"); string b("world"); string c =a ;   //拷贝构造函数 c = b;           //调用赋值函数 一般来说是在数据成员包含指针对象的时候,应付两种不同的处理需求的 一种是复制指针对象,一种是引用指针对象

C++ String类 ( 构造、拷贝构造、赋值运算符重载和析构函数)

class String { public: //普通构造函数 String(const char *str = NULL) { if(str == NULL) { m_data = new char[1]; *m_data = '\0'; } else { m_data = new char[strlen(str) + 1]; strcpy(m_data, str); } } //拷贝构造函数 String(const String &s) { m_data = new char[strlen

C/C++(C++拷贝构造器,赋值运算符重载)

拷贝构造器 由己存在的对象,创建新对象.也就是说新对象,不由构造器来构造,而是由拷贝构造器来完成.拷贝构造器的格式是固定的. class 类名 { 类名(const 类名 & another) 拷贝构造体 } class A { A(const A & another) {} } 规则: 1 系统提供默认的拷贝构造器.一经实现,不复存在. 2 系统提供的时等位拷贝,也就是所谓的浅浅的拷贝. 3 要实现深拷贝,必须要自定义. 4 浅拷贝,会导致内存重析构.linux下浅拷贝会挂机.doubl

C++ STL主要组件之String总结(第二部分 深、浅拷贝问题以及赋值运算符重载)

第一部分连接https://blog.51cto.com/14232799/2447326 二.String的模拟实现 在第一步之后紧接着的就该是模拟实现部分,这一部分主要是体现自己对第一部分的掌握情况.强烈推荐和我一样在学习String的朋友们自己动手实现一下.因为在面试中,面试官总喜欢让我们自己来模拟实现string类. 自己来实现String最主要是实现String类的构造.拷贝构造.赋值运算符重载(第一部分operator开头的方法)以及析构函数. 以下是我完成的基础模拟实现 #incl