剑指Offer系列---(3)赋值运算符函数
2015-09-06 10:07
246 查看
1.题目描述:
赋值运算符函数
2.考虑情况:
1)是否把返回值的类型声明为该类型的引用,并在函数结束前返回实例自身的引用(即*this)。只有返回一个引用,才可以允许连续赋值。否则如果函数的返回值是void,应用该赋值运算符将不能做连续赋值。假设有3个CMyString的对象:str1,str2和str3,在程序中语句str1=str2=str3将不能通过编译;
2)是否把传入的参数的类型声明为常量引用。如果传入的参数不是引用而是实例,那么从形参到实参会调用一次复制构造函数,把参数声明为引用可以避免这样的无谓消耗,能提高代码的效率。同时我们在赋值运算符函数内不会改变传入的实例的状态,因此应该为传入的引用参数加上const关键字;
3)是否释放实例自身已有的内存。如果我们忘记在分配新内存之前释放自身已有的空间,程序将出现内存泄露;
4)是否判断传入的参数和当前的实例(*this)是不是同一个实例。如果是同一个,则不进行赋值操作,直接返回。如果事先不判断就进行赋值,那么在释放实例自身的内存的时候就会导致严重的问题:当*this和传入的参数是同一个实例时,那么一旦释放了自身的内存,传入的参数的内存也同时被释放了,因此再也找不到需要赋值的内容了。
3.源代码:
赋值运算符函数
2.考虑情况:
1)是否把返回值的类型声明为该类型的引用,并在函数结束前返回实例自身的引用(即*this)。只有返回一个引用,才可以允许连续赋值。否则如果函数的返回值是void,应用该赋值运算符将不能做连续赋值。假设有3个CMyString的对象:str1,str2和str3,在程序中语句str1=str2=str3将不能通过编译;
2)是否把传入的参数的类型声明为常量引用。如果传入的参数不是引用而是实例,那么从形参到实参会调用一次复制构造函数,把参数声明为引用可以避免这样的无谓消耗,能提高代码的效率。同时我们在赋值运算符函数内不会改变传入的实例的状态,因此应该为传入的引用参数加上const关键字;
3)是否释放实例自身已有的内存。如果我们忘记在分配新内存之前释放自身已有的空间,程序将出现内存泄露;
4)是否判断传入的参数和当前的实例(*this)是不是同一个实例。如果是同一个,则不进行赋值操作,直接返回。如果事先不判断就进行赋值,那么在释放实例自身的内存的时候就会导致严重的问题:当*this和传入的参数是同一个实例时,那么一旦释放了自身的内存,传入的参数的内存也同时被释放了,因此再也找不到需要赋值的内容了。
3.源代码:
// Copyright (c) 2015年 skewrain. All rights reserved. // #include <iostream> #include <stdio.h> using namespace std; class CMyString { public: CMyString(char* pData = NULL); //CMyString(const CMyString& str); ~CMyString(void); //声明返回值的类型为引用,才可以允许连续赋值 CMyString& operator = (const CMyString &str); void Print(); private: char* m_pData; }; CMyString::CMyString(char *pData) { if(pData == NULL) { m_pData = new char[1]; m_pData[0] = '\0'; } else { int length = (int)strlen(pData); m_pData = new char[length+1]; strcpy(m_pData,pData); } } CMyString::~CMyString() { delete []m_pData; } CMyString& CMyString::operator=(const CMyString& str) { if (this == &str) { return *this; } delete []m_pData; m_pData = NULL; m_pData = new char[strlen(str.m_pData)+1]; strcpy(m_pData, str.m_pData); return *this; } void CMyString::Print() { cout<<m_pData<<endl; } void test1()//普通赋值 { cout<<"test1() begins:"<<endl; char *text = "hello world"; CMyString str1(text); CMyString str2; str2 = str1; cout<<"The expected result is:"<<text<<endl; cout<<"The actual result is:"; str2.Print(); cout<<endl; } void test2()//自身赋值 { cout<<"test2()begins:"<<endl; char *text = "hello world"; CMyString str1(text); str1 = str1; cout<<"The expected result is:"<<text<<endl; cout<<"the acutal result is:"; str1.Print(); cout<<endl; } void test3()//连续赋值 { cout<<"test3() begins:"<<endl; char *text = "hello world"; CMyString str1(text); CMyString str2,str3; str3 = str2 = str1; cout<<"The expected result is:"<<text<<endl; cout<<"the actual result is:"; str2.Print(); cout<<endl; cout<<"The expected result is:"<<text<<endl; cout<<"the actual result is:"; str3.Print(); cout<<endl; } int main(int argc, const char * argv[]) { test1(); test2(); test3(); return 0; }
相关文章推荐
- jQuery对象与dom对象的区别与相互转换
- [leetcode]51 Delete Node in a Linked List
- CSS3变形属性:CSS33DTransform
- js中立即执行函数的介绍
- CSS3 RGBA
- jquery基本语法
- caffe for Windows下的编译错误
- jquery JSON的解析方式
- Jquery实现拖动
- C# if,ifelse语句
- 读取文本文件里的Json数据
- iOS7之后JavaScript与Objective-C之间的通信
- javascript深入理解js闭包
- 浅谈javascript函数式编程
- CSS HACK
- jquery加载页面的方法(页面加载完成就执行)
- jquery基础知识实例(一)
- JqueryMobile动态生成listView并实现刷新的两种方法
- PHP javascript 实现将将一句话分解成包含所有单词的一个数组
- 【bzoj2257】【jsoi2009】【瓶子和燃料】【裴蜀定理】