• 30.赋值运算符重载函数[Assign copy constructor]


    【问题】

    给出如下CMyString的声明,要求为该类型添加赋值运算符函数。

     C++ Code 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     

    class CMyString
    {
    public:
        CMyString(
    char *pData = NULL);
        CMyString(
    const CMyString &str);
        ~CMyString(
    void);

    private:
        
    char *m_pData;
    };

    分析】

    当我们完整地考虑了上述几方面之后,我们可以写出如下的代码:

     C++ Code 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     

    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;
    }

    面试官会提醒我们在前面的函数中,显示地用delete释放自身m_pData的内存。同时我们也会在析构函数中用delete释放自身m_pData的内存。如果这个类型中添加新的指针成员变量,那么我们至少需要做两处修改,即同时在析构函数和这个赋值运算符函数里添加一条delete语句来释放新指针所指向的内存。一个改动需要在代码中多个地方修改代码,通常是有安全隐患的。通常我们会记得在析构函数里用delete释放指针成员变量,但未必每次都记得到赋值运算符函数来添加代码释放内存。

    更好的办法在复制运算符函数中利用析构函数自动释放实例已有的内存。

    【代码】

     C++ Code 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     

    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;
    }

    在这个函数中,我们定义一个临时实例strTemp,并把strTemp的m_pData指向当前实例(*this)的m_pData。由于strTemp是个局部变量,但程序员运行到if的外面是也就出了的该变量的域,就会自动调用strTemp的析构函数,就会把strTemp.m_pData所指向的内存释放掉。由于strTemp.m_pData指向的内存就是当前实例之前m_pData的内存。这就相当于自动调用析构函数释放当前实例的内存。如果新增加指针成员变量,我们只需要在析构函数里正确地释放,而不需要对赋值运算符函数做任何修改。

    【参考】

    http://zhedahht.blog.163.com/blog/static/25411174200741543224391/

    个人学习笔记,欢迎拍砖!---by hellogiser

    Author: hellogiser
    Warning: 本文版权归作者和博客园共有,欢迎转载,但请保留此段声明,且在文章页面明显位置给出原文连接。Thanks!
    Me: 如果觉得本文对你有帮助的话,那么【推荐】给大家吧,希望今后能够为大家带来更好的技术文章!敬请【关注】
  • 相关阅读:
    python 四舍五入
    Elasticsearch 入门
    Mac下ElasticSearch安装、Kibana
    Mysql 终端中文显示乱码
    Zookeeper 在 Kafka 中的作用
    mac 安装Kafka
    Creating a NuGet Package in 7 easy steps
    Updating and Publishing a NuGet Package
    ASP.NET Core 发布
    An entry point cannot be marked with the 'async' modifier
  • 原文地址:https://www.cnblogs.com/hellogiser/p/3738865.html
Copyright © 2020-2023  润新知