码迷,mamicode.com
首页 > 编程语言 > 详细

陷阱重重的C++赋值重载函数operator=

时间:2014-11-12 10:37:32      阅读:197      评论:0      收藏:0      [点我收藏+]

标签:c++   编程   

曾经有C++高手说过:看一个C++程序员功底是否够硬,让他写个赋值重载函数就能看出来了!在我看来,这种说法并不夸张。因为能将operator=函数写好确实需要扎实的基础,其中的陷阱真不少。

  • 陷阱一:不懂规避自我拷贝

先看代码

string& string::operator=(const string& rhs)
{
    if (m_pStr != NULL)
        delete [] m_pStr;
    m_pStr = new char[....];
    strcpy(....);

    return *this;
}

此代码就是没有规避自我赋值,那么如果进行以下的调用,那么后果很严重。

string myStr("abc");
myStr = myStr;

赋值操作中,会先把自己的数据delete掉,然后再strcpy一个空值,程序立马挂了。

所以,在赋值函数开始的时候,需要防止自我复制。写法如下:

string& string::operator=(const string& rhs)
{
    // 防止自我赋值
    if (this == &rhs)
        return * this;

    ...
}
但有些书籍上面使用以下写法,不敢苟同。

string& string::operator=(const string& rhs)
{
    // 防止自我赋值
    if (*this == rhs) // 这只是判断内容是否相同,并不能判定是自我赋值!!!
        return * this;

    ...
}
  • 陷阱二:返回值的类型用啥

在初学者的群体当中,有出现诸如以下几种返回值版本:

// 版本一
string string::operator=(const string& rhs)
{
    ...
    return * this;
}

// 版本二
const string& string::operator=(const string& rhs)
{
    ...
    return * this;
}

// 版本三
string* string::operator=(const string& rhs)
{
    ...
    return this;
}

版本一的缺陷:多了一个临时对象的生成和拷贝,影响程序效率。

版本二的缺陷:非const类型的变量想得到它的连续赋值变得不可能,而且编译器也会报错。

版本三的缺陷:不能保持连续赋值时类型的统一性,违反了编程的惯例。如

// 版本三的缺陷
string a, b, c;
*a = b = c; // 必须这样赋值给a,类型不统一!! 
  • 陷阱三:未做深拷贝

任何未做深拷贝的版本都退化为默认版本。

string& string::operator=(const string& rhs)
{
    if (this == &rhs) return *this;

    if (m_pStr != NULL)
        delete [] m_pStr;
    m_pStr = rhs.m_pStr; // 浅拷贝

    return *this;
}


陷阱重重的C++赋值重载函数operator=

标签:c++   编程   

原文地址:http://blog.csdn.net/linqingwu75/article/details/40993139

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!