面试题1:赋值运算符函数

博客主要围绕函数的异常安全性展开,指出异常安全需满足不泄漏资源和不破坏数据。还阐述了赋值运算符函数要满足的四个要点,如返回引用、参数声明为常量引用等。此外,介绍了实现异常安全性的两种方法,最后提及struct和class的访问权限区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先应该考虑异常安全性

https://blog.youkuaiyun.com/bonchoix/article/details/8046727

一个函数如果说是“异常安全”的,必须同时满足以下两个条件:1.不泄漏任何资源;2.不允许破坏数据。 (内存泄漏:指程序在申请内存后,无法释放已申请的内存空间)

其次要满足四个点:

1.把返回值的类型声明为该类型的引用,并在函数结束前返回实例自身的引用(*this)。只有返回一个引用,才可以允许连续赋值(从右到左),否则无法通过编译。

2.把传入的参数声明为常量引用,假如是实例,从形参到实参会调用一次复制构造函数,声明为引用可以避免无谓消耗,提高代码的效率;同时在赋值运算符函数内不会改变传入的实例的状态,需要加上const关键字。

3.先判断是否自复制,假如在分配新内存之前释放自身已有的空间,则程序将出现内存泄漏。

4.假如不是自复制,先回收左操作数指针指向的原来的空间,再进行深拷贝。

 

Computer & operator=(const Computer & rhs)
{
    cout << "Computer & operator=(const Computer & rhs)" << endl;
    if(this != &rhs)//1.先判断是否是自复制
    {
        delete [] _brand;//2. 回收左操作数指针原来的空间
        this->_brand = new char[strlen(rhs._brand)+1]();//3. 深拷贝
        //+1是指字符串的\0,()是指将new空间初始化
        strcpy(_brand, rhs._brand);
        
        _price = rhs._price;
    }
    return *this;
}

剑指offer源码:

https://github.com/zhedahht/CodingInterviewChinese2/blob/master/01_AssignmentOperator/AssignmentOperator.cpp

 

假如需要实现异常安全性,有两种方法。

一种是先用new分配新内容,再用delete释放已有的内容,也就是保证了分配内存失败时我们可以确保该类的实例不会被修改

另一种是先创建一个临时实例,再交换临时实例和原来的实例,代码如下:

CMyString & CMyString::operator=(const CMyString & str)
{
    if(this != &str)
    {
        CMyString strTemp(str);
        
        char * pTemp = strTemp.m_pData;
        strTemp.m_pData = m_pData;
        m_pData = pTemp;
    }
    return * this;
}

重点是对代码的异常安全性的理解

 

struct 和 class的区别是:如果没有标明成员函数或者成员变量的访问权限级别,那么在struct中默认的是public,而在class中默认的是private。

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值