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

可运行的总代码: 

#pragma warning(disable:4996)
#include <string.h>
#include <cstdio>
#include <iostream>

//using std::cout;
//using std::cin;
//using std::endl;
using namespace std;

class CMyString
{
public:
    CMyString();//无参构造函数
    CMyString(const char* m_pDate);//有参构造函数
    CMyString(const CMyString& str);//深拷贝
    CMyString& operator=(const CMyString& str);//赋值运算符函数
    ~CMyString(void);//析构函数

    void print() {
        if (m_pDate) {
            cout << m_pDate << endl;
        }
    }

    void swap(CMyString& str) {
        std::swap(m_pDate, str.m_pDate);
    }

    size_t length() const {
        return strlen(m_pDate);
    }

    const char* c_str() const {
        return m_pDate;
    }

private:
    char* m_pDate;
};
CMyString::CMyString()
    :m_pDate(new char[1]())
{
    cout << "CMyString()" << endl;
}



CMyString::CMyString(const char* pData)
    :m_pDate(new char[strlen(pData) + 1]())
{
    strcpy(m_pDate, pData);
    cout << "CMyString(const char*)" << endl;
}

CMyString::CMyString(const CMyString& str)
    :m_pDate(new char[str.length() + 1]())
{
    strcpy(m_pDate, str.m_pDate);
    cout << "CMyString(const CMyString&)" << endl;
}


//考察代码:赋值运算符函数
CMyString& CMyString::operator=(const CMyString& str)
{
    if (this != &str) {
        CMyString strTemp(str);

        char* pTemp = strTemp.m_pDate;
        strTemp.m_pDate = m_pDate;
        m_pDate = pTemp;
    }
    return *this;
}


CMyString::~CMyString()
{
    if (m_pDate) {
        delete[] m_pDate;
        m_pDate = nullptr;
    }

    cout << "~CMyString()" << endl;
}
void test0()
{
    CMyString s1;
    cout << 1;
    s1.print();

    CMyString s2 = "hello";
    cout << 2;
    s2.print();

    CMyString s3(s2);
    cout << 3;
    s3.print();

  

    CMyString s7, s8;
    s7 = s8 = s3;//连续赋值
    s7.print();
    s8.print();
    s3.print();
}


int main(void)
{
    test0();

    return 0;
}

运行结果:

CMyString()
1
CMyString(const char*)
2hello
CMyString(const CMyString&)
3hello
CMyString()
CMyString()
CMyString(const CMyString&)
~CMyString()
CMyString(const CMyString&)
~CMyString()
hello
hello
hello
~CMyString()
~CMyString()
~CMyString()
~CMyString()
~CMyString()

考察代码:

CMyString& CMyString::operator=(const CMyString& str)/*CMyString&:把返回值的类型声明为该类型的引用,只有返回一个引用,才可以允许连续赋值。CMyString& str:把传入的参数的类型声明为常量引用,形参到实参不会调用复制构造函数,提高代码效率。const:且在此函数里不会改变传入的实例的状态,因此加上const关键字。*/
{
    if (this != &str) {/*需判断传入的参数str与当前的实例this是不是同个实例,如果是同一个,则不进行赋值操作,直接返回。因为当需判断传入的参数str与当前的实例this是同个实例,一但释放了自身this的内存,传入的参数str的内存也同时被释放掉了,因此找不到需要赋值的内容了*/
        CMyString strTemp(str);/*创建一个临时变量strTemp,值为实例的值,strTemp的作用域只在if代码块里生效,除了if代码块,程序自动调用strTemp的析构函数,(strTemp指向的内存与str是一样的,)结果会把形参的实例所指向的内存释放掉*/

        char* pTemp = strTemp.m_pDate;/*以下是交换临时变量实例strTemp与原来的实例this*/
        strTemp.m_pDate = m_pDate;
        m_pDate = pTemp;
    }
    return *this;//返回一个指针类型的变量
}

额外知识:
m_pDate=new char[strlen(str.m_pDate)+1];//这种方式用new分配内存,如果此时内存不足导致new char抛出异常,则m_pDate将是个空指针。

 CMyString strTemp(str);//在构造函数里用new分配内存,(用str实例给当前实例this赋值),如果由于内存不足抛出诸如bad alloc等异常,抛出异常则不会修改当前实例的状态,当前实例状态还是有效的,保证了异常安全性。

delete []m_pDate;//在给当前实例分配新内存之前需释放自身已有的空间,否则程序将出现内存泄漏。

代码参考以往的csdn社区博客作出。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值