赋值函数
        每个类只有一个赋值函数  
        由于并非所有的对象都会使用拷贝构造函数和赋值函数,程序员可能对这两个函数有些轻视。
    1,如果不主动编写拷贝构造函数和赋值函数,编译器将以“位拷贝”的方式自动生成缺省的函数。倘若类中含有指针变量,那么这两个缺省的函数就隐含了错误。
               以类String的两个对象a,b为例,假设a.m_data的内容为“hello”,b.m_data的内容为“world”。   
               现将a赋给b,缺省赋值函数的“位拷贝”意味着执行b.m_data = a.m_data。
               这将造成三个错误:             
                        一是b.m_data原有的内存没被释放,造成内存泄露;
                        二是b.m_data和a.m_data指向同一块内存,a或b任何一方变动都会影响另一方;
                        三是在对象被析构时,m_data被释放了两次。   
        2,拷贝构造函数和赋值函数非常容易混淆,常导致错写、错用。拷贝构造函数是在对象被创建时调用的,而赋值函数只能被已经存在了的对象调用。以下程序中,第三个语句和第四个语句很相似,你分得清楚哪个调用了拷贝构造函数,哪个调用了赋值函数吗?  
           String a(“hello”);   
             String b(“world”); 
             String c = a;   // 调用了拷贝构造函数,最好写成 c(a); 
          c = b;      // 调用了赋值函数   
               本例中第三个语句的风格较差,宜改写成String c(a) 以区别于第四个语句。   
        类String的拷贝构造函数与赋值函数   
 // 拷贝构造函数            
         String::String(const String &other)   
         {   
             int length = strlen(other.m_data);  // 允许操作other的私有成员m_data 
               m_data = new char[length+1];  
             strcpy(m_data, other.m_data);  
      }   
// 赋值函数   
      String & String::operator =(const String &other)   
       {  
                if(this == &other)          // (1) 检查自赋值
                          return *this;   
          delete [] m_data;            // (2) 释放自己原有的内存资源 
              int length = strlen(other.m_data);     // (3)分配新的内存资源,并复制内容
            m_data = new char[length+1];   
              strcpy(m_data, other.m_data);   
            
              return *this;              // (4)返回本对象的引用
   }   
      类String拷贝构造函数与普通构造函数的区别是:在函数入口处无需与NULL进行比较,这是因为“引用”不可能是NULL,而“指针”可以为NULL。 
   类String的赋值函数比构造函数复杂得多,分四步实现:   
                (1)第一步,检查自赋值。你可能会认为多此一举,难道有人会愚蠢到写出 a = a 这样的自赋值语句!的确不会。但是间接的自赋值仍有可能出现,例如   // 内容自赋值   b = a;   …   c = b;   …   a = c;   // 地址自赋值   b = &a;   …   a = *b;   也许有人会说:“即使出现自赋值,我也可以不理睬,大不了化点时间让对象复制自己而已,反正不会出错!”   他真的说错了。看看第二步的delete,自杀后还能复制自己吗?所以,如果发现自赋值,应该马上终止函数。注意不要将检查自赋值的if语句   if(this == &other)   错写成为   if( *this == other)   
               (2)第二步,用delete释放原有的内存资源。如果现在不释放,以后就没机会了,将造成内存泄露。   
               (3)第三步,分配新的内存资源,并复制字符串。注意函数strlen返回的是有效字符串长度,不包含结束符‘\0’。函数strcpy则连‘\0’一起复制。   
               (4)第四步,返回本对象的引用,目的是为了实现象 a = b = c 这样的链式表达。注意不要将 return *this 错写成 return this 。那么能否写成return other 呢?效果不是一样吗?       不可以!因为我们不知道参数other的生命期。有可能other是个临时对象,在赋值结束后它马上消失,那么return other返回的将是垃圾。   偷懒的办法处理拷贝构造函数与赋值函数   如果我们实在不想编写拷贝构造函数和赋值函数,又不允许别人使用编译器生成的缺省函数,怎么办?

C++赋值函数详解的更多相关文章

  1. javascript 函数详解2 -- arguments

    今天我们接着上篇文章来继续javascript函数这个主题.今天要讲的是函数对像中一个很重要的属性--arguments. 相关阅读: javascript 函数详解1 -- 概述 javascrip ...

  2. ThinkPHP函数详解:session方法

    ThinkPHP函数详解:session方法 Session方法用于Session 设置.获取.删除和管理操作. Session 用于Session 设置.获取.删除和管理操作 用法    sessi ...

  3. windows socket函数详解

    windows socket函数详解 近期一直用第三方库写网络编程,反倒是遗忘了网络编程最底层的知识.因而产生了整理Winsock函数库的想法.以下知识点均来源于MSDN,本人只做翻译工作.虽然很多前 ...

  4. PHP输出缓存ob系列函数详解

    PHP输出缓存ob系列函数详解 ob,输出缓冲区,是output buffering的简称,而不是output cache.ob用对了,是能对速度有一定的帮助,但是盲目的加上ob函数,只会增加CPU额 ...

  5. loadrunner 脚本优化-关联函数web_reg_save_param()函数详解

    脚本优化-关联函数web_reg_save_param()函数详解   by:授客 QQ:1033553122 Insert->New Step,打开Add Step对话框 选择函数web_re ...

  6. AdapterView的使用与getView函数详解

    作者:徐冉.文章首发在他的个人博客. ) AdapterView&Adapter家族 adapterview就是和数据有关的控件,如listview,gridview,spinnerview等 ...

  7. C++ list容器系列功能函数详解

    C++ list函数详解 首先说下eclipse工具下怎样debug:方法:你先要设置好断点,然后以Debug方式启动你的应用程序,不要用run的方式,当程序运行到你的断点位置时就会停住,也会提示你进 ...

  8. C语言memset函数详解

    C语言memset函数详解 memset() 的作用:在一段内存块中填充某个给定的值,通常用于数组初始化与数组清零. 它是直接操作内存空间,mem即“内存”(memory)的意思.该函数的原型为: # ...

  9. CString 的成员函数详解

    CSTRING的成员函数详解   typedef ATL::CStringT< TCHAR, StrTraitMFC_DLL< TCHAR > > CString;CStrin ...

随机推荐

  1. iOS 技能集结号

    1. 获取磁盘总空间大小 2. 获取磁盘可用空间大小 3. 获取指定路径下某个文件的大小 4. 获取文件夹下所有文件的大小 5. 获取字符串(或汉字)首字母 6. 将字符串数组按照元素首字母顺序进行排 ...

  2. bootstrap table笔记

    获取选中行:$table.bootstrapTable('getSelections');

  3. java ee环境搭建

    1.安装java(tm)2 platform 2.下载安装Java EE SDK 版本:Java Platform,Enterprise Edition 7 SDK (with JDK 7u45) 下 ...

  4. objectiveC获取本地时间。

    NSDate * date = [NSCalendarDate date]; NSLog(@"%@", date); 日历在IOS里报错,,. NSDateFormatter *f ...

  5. Vim键盘布局

     Vim键盘布局 用Linux的朋友一定会使用到Vim这个文本编辑器,它是由Vi发展而来的编辑器,其具有代码补齐.编译.错误跳转等丰富的功能,非常适合编程.对于修改Linux配置文件它更是你不二的选择 ...

  6. Qt多线程编程总结(二)——QMutex

    QMutex类提供的是线程之间的访问顺序化. QMutex的目的是保护一个对象.数据结构或者代码段,所以同一时间只有一个线程可以访问它.(在Java术语中,它和同步关键字“synchronized”很 ...

  7. angulajs 如何在controller 之间共享数据

    当在一个controller中 通过设置$scope的数据,来影响其它control的范围时,可以使用$rootScope 举个例子: 在一个control A范围内设置 mainApp.contro ...

  8. Spring 面试复习

    1   singleton 和 prototype singleton作用域:当把一个Bean定义设置为singleton作用域是,Spring IoC容器中只会存在一个共享的Bean实例,并且所有对 ...

  9. Qt 4.6: A Quick Start to Qt Designer

    Qt 4.6: A Quick Start to Qt Designer A Quick Start to Qt Designer Using Qt Designer involves four ba ...

  10. CSS3属性值之box-shadow

    语法:   box-shadow:inset x-offset y-offset blur-radius spread-radius color 也就是:   对象选择器 {box-shadow:投影 ...