String类赋值运算符函数

原创 2016年06月01日 22:22:54

题目:如下类型CMyString的声明,请为该类添加赋值运算符函数

class CMyString
{
public:
    CMyString(char* pdata = NULL);
    CMyString(const CMyString& str);
    //赋值函数
    CMyString& operator=(const CMyString& str); 

    ~CMyString(); 

private:
    char* m_data;
};

面试官考察的点:
1、 是否把返回值的类型声明为该类型的引用,并在函数返回前,返回自身的引用(*this)。只有返回一个引用,才可以允许连续赋值。如果函数的返回值为void,则像str1=str2=str3这样的连续赋值将不会被通过
2、 是否把传入的参数类型声明为常引用。如果传入的参数不是引用而是实=实例的话,那么从形参到实参要进行一次拷贝构造函数的调用,把参数声明为引用,可以避免无谓的消耗,提高效率。同时,在赋值的时候,不应该改变传入参数的状态,所以,应该声明为常引用,加上const关键字
3、 是否释放自身的空间,否则程序将出现内存泄漏
4、 避免自赋值。判断传入的参数是否和当前的实例*this是一个实例,如果是同一个实例,则不进行赋值操作,直接返回。如果事先不进行判断,在释放自身实例的内存的时候就会出现问题,一旦释放了自身的内存,传入的参数的内存也同时释放了,因此再也找不到需要赋值的内容了

//初级程序员解法:

CMyString& CMyString::operator=(const CMyString& str)
{
    //防止自赋值
    if (&str == this)
        return *this;
    //释放自身空间
    delete[] m_data;
    m_data = NULL; 
    //分配空间,赋值
    m_data = new char[strlen(str.m_data)+1]; 
    strcpy(m_data, str.m_data); 

    //返回自身引用
    return *this; 
}

//考虑异常安全的解法,高级程序员必备
在前面的函数中,我们在分配内存之前先delete释放了自身的内存。但是如果此时内存不足,分配内存的时候抛出异常,那么m_data将是一个空指针,很容易导致程序崩溃,违背了异常安全原则
要想在赋值函数中实现异常安全性。有两种方法:1、一个简单的方法是先用new分配新内容,再delete释放已有的内容,这样在分配成功之后再释放原来的内容,也就是当分配失败时可以保证CMyString的实例不会被修改。2、还有一个更好的方法就是创建一个临时对象,再交换临时对象和原来对象

CMyString& CMyString::operator=(const CMyString& str)
{
    if (&str != this)
    {
        //先通过拷贝构造函数创建一个临时对象 
        CMyString strtmp(str);
        //交换临时对象和自身的m_data
        char* pTmp = m_data;
        m_data = strtmp.m_data;
        strtmp.m_data = pTmp; 

    }
    return *this;
}

这个函数中,先创建一个临时对象,然后交换临时对象和实例自身的m_data,由于临时对象是一个局部对象,出了if语句就会自动调用临时对象的析构函数,就会把临时对象所指的那块内存释放掉。
在这个新的代码中,我们在CMyString的构造函数里用new分配内存,如果内存不足抛出异常,这时,我们还没有修改原来实例的状态。就保证了异常安全性

版权声明:本文为博主原创文章,未经博主允许不得转载。

为string类添加一个赋值运算符函数

面试中经常会被要求写一个string类,其实通过写string类就可以看出来一个人对C++的掌握能力。其实写string类主要就是看赋值运算符的重载函数的写法。在这里我自己实现了两种。如果大家有更好的...

C++常见笔试面试题目:string类的拷贝赋值运算符函数

要求:写出一个String类的赋值运算符函数 注意事项: (1)返回值的类型需声明为该类型的引用,并在函数结束前返回实例自身的引用(即*this),因为只有返回一个引用,才可以允许连续赋值。 (...
  • hmxz2nn
  • hmxz2nn
  • 2016年11月11日 17:08
  • 182

C++面试题,自己实现String类的构造函数,拷贝构造函数,赋值操作符,append,replace,+运算符重载等

#include "string.h" #include using namespace std; class String { public:  String(const char *...

string赋值运算符、复制构造函数等实现

本题来源于《剑指oOfer》24页,面试题1:赋值运算符函数,主要实现一个简单的stringleiu...
  • whuexe
  • whuexe
  • 2014年04月16日 22:36
  • 492

C++:运算符重载、string类重写、数据类型转换、->操作符重载、virtual继承、virtual函数、typeid

1.运算符重载 谁调用了成员函数,谁就是当前对象。在C++中运算符操作就是函数。含有const或者引用成员变量时,构造函数要人为的初始化。Int i=9; cout>代码如下:istream &...

模拟实现C++ string类(构造、析构、拷贝、赋值运算符重载)

在面试过程中,如果要让写一个string类的模拟,那么,面试官多半是想考你关于深浅拷贝的某些知识。         对于string类的实现来说,比较重要的几个成员函数,也就是构造函数、析构函数、拷贝...
  • Ren_X
  • Ren_X
  • 2016年08月04日 09:00
  • 298

C#从入门到精通读书笔记 运算符、string类、string函数(二)

关系运算符返回的是布尔值;

python的【字符串string】:运算符、内建函数

Python字符串运算符 下表实例变量a值为字符串"Hello",b变量值为"Python": 操作符 描述 实例 + 字符串连接 a + b 输出结果: HelloPytho...
  • mmc2015
  • mmc2015
  • 2015年08月23日 22:48
  • 1091

C++:类的复制构造函数、赋值运算符

from : http://blog.csdn.net/lwbeyond/article/details/6202256
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:String类赋值运算符函数
举报原因:
原因补充:

(最多只允许输入30个字)