剑指offer 1 复制控制

来源:互联网 发布:js代码自动触发事件 编辑:程序博客网 时间:2024/05/16 10:19

1. 需要把返回值得类型声明定义为该类型的引用, 并且在函数结束前返回实例自身的引用 (*this). 只有返回引用才可以连续赋值

2. 需要把传入参数的类型声明为常量引用. 形参必须是引用, 否则会编译报错

3. 需要判断引入的实例是否是当前实例, 如果是同一个那么不进行赋值, 直接返回. 如果不事先判断就直接赋值, 那么在释放实例内存时就会出现严重的问题. 若传入实例释放了自己的内存, 并且 传入实例就是当前实例, 那么不仅没完成赋值, 当前实例也不完整了

4. 异常安全性. 先创建再复制, 代码如下

#include<iostream>using namespace std;class MyClass{public:MyClass(char* pData   )  // 普通构造函数{ if(pData==NULL)   //加分点:对pData加NULL 判断        {              m_pData = new char[1]; // 得分点:对空字符串自动申请存放结束标志'\0'的              *m_pData = '\0';        }            else        {             m_pData = new char[strlen(pData)+1]; // 若能加 NULL 判断则更好             strcpy(m_pData, pData);        }}MyClass(const MyClass & myclass)   // 拷贝构造函数    得分点:输入参数为const型{ m_pData = new char[strlen(myclass.m_pData)+1];  //注意'\0'         strcpy(m_pData, myclass.m_pData);        }    MyClass& operator = (const MyClass &myclass)  // 赋值函数{   if(this != &myclass)   //得分点:检查自赋值{           delete []m_pData;  //得分点:释放原有的内存资源        m_pData=NULL;        m_pData = new char[strlen(myclass.m_pData)+1];if(m_pData == NULL)return *this;  //加分点:对m_pData加NULL 判断strcpy(m_pData,myclass.m_pData);} //  if(this != &myclass)//{   //MyClass temp(myclass); //创建一个临时实例      //char *pTemp = temp.m_pData;//temp.m_pData=m_pData; //交换  //          m_pData=pTemp;  //  }   return *this;    //得分点:返回本对象的引用  }void print(){std::cout<<m_pData;}~MyClass(){delete [] m_pData;}private:char* m_pData;};#include<iostream>int main(){  MyClass my("sds");  MyClass my2 = my;  //赋值给另一个实例   my = my; //赋值给自己  for(int i=0;i<10;i++)      my="sd";  //连续赋值  my.print();  my2.print();}


0 0
原创粉丝点击