【剑指offer】面试题1:赋值运算符函数【C++版本】

40 篇文章 1 订阅
26 篇文章 1 订阅

总结的部分题目思路与代码,待完善。
【剑指offer-第二版】部分题目与解答【C++版本】

题目:

赋值运算符函数

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

class CMyString {
public:
    //构造函数
    CMyString(char *pData = nullptr);
    //拷贝构造函数
    CMyString(const CMyString &str);
    //赋值运算符函数
    CMyString &operator=(const CMyString &str);
private:
    char *m_pData;
};

解题思路:

1.对于初级:

1).返回类型为该类型的引用、函数结束前返回实例自身的引用(这样才能允许连续赋值)return *this;
2).把形参声明成该类型的常量引用,避免不必要的拷贝构造;
3).如果有必要,需要释放实例自身已经拥有的内存;
4).判断传入的参数和当前的实例(*this)是不是同一个实例(判断自赋值的情况);

2.对于高级程序员还应该判断会不会因为内存不足而导致new失败,解决办法有二 :

1).先new分配空间,然后再delete释放。只有在分配空间成功后才释放原有内容,即分配失败时我们可以保证原有内容保存下来;
2).先使用拷贝构造函数创建一个临时实例,然后交换临时实例和自身。临时实例在拷贝赋值函数之后自动析构了,且如果临时实例分配内存失败,也不会改变原有内容。

另外对于拷贝构造函数:

1.其实就是一个构造函数,不过形参是该类型本身。
2.形参为const的引用,因为拷贝不影响原变量。如果不使用引用会无限循环调用构造函数。
3.在给新建变量赋值时会引用。而赋值运算符用在给已存在的变量赋值的情况。

方法一【C++版本】

CMyString.h文件中

#pragma once

class CMyString {
public:
    CMyString(char *pData = nullptr);
    //拷贝构造函数
    //因为是新建立的变量,所以不用考虑自赋值,不用考虑释放旧值
    CMyString(const CMyString &);
    ~CMyString();
    CMyString &operator=(const CMyString &str);
    char *getData();
private:
    char *m_pData;
};
CMyString.cpp文件中

#include "CMyString.h"
#include <string.h>
#include <iostream>

using namespace std;

CMyString::CMyString(char *pData){
    m_pData = new char[strlen(pData) + 1];
    strcpy(m_pData, pData);
}

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

//拷贝构造函数
//参数还是使用const的引用,因为不会改变参数的值,如果不使用引用,这里会存在无限赋值的情况
CMyString::CMyString(const CMyString &str) {
    cout << "这是拷贝构造函数!" << endl;
    m_pData = new char[strlen(str.m_pData) + 1];
    strcpy(m_pData, str.m_pData);
}

//赋值运算符函数
CMyString &CMyString::operator=(const CMyString &str) {
    cout << "这是拷贝赋值运算符!" << endl;
    if (this == &str) {
        //检查自赋值的情况
        return *this;
    }

    //释放原本的内存
    if (m_pData) {
        delete[] m_pData;
        m_pData = nullptr;
    }

    m_pData = new char[strlen(str.m_pData) + 1];
    strcpy(m_pData, str.m_pData);

    return *this;
}

char *CMyString::getData() {
    return m_pData;
}
main.cpp中的测试程序

#include "CMyString.h"
#include <string>
#include <iostream>

using namespace std;

int main()
{
    char *tmp = "hello world";
    CMyString myStr(tmp);

    cout << "myStr: " << myStr.getData() << endl;

    CMyString otherOne = myStr;

    cout << "otherOne: " << otherOne.getData() << endl;

    char *tmp2 = "show the difference.";
    CMyString myStr2(tmp2);
    cout << "myStr2: " << myStr2.getData() << endl;

    myStr2 = otherOne;
    cout << "myStr2 after operator \"=\": " << myStr2.getData() << endl;

    system("pause");
    return 0;
}
输出结果:
myStr: hello world
这是拷贝构造函数!
otherOne: hello world
myStr2: show the difference.
这是拷贝赋值运算符!
myStr2 after operator "=": hello world
请按任意键继续. . .

方法二:考虑new分配空间是否足够【C++版本】

CMyString &CMyString::operator=(const CMyString &str) {
    if (this != &str) {
        //调用拷贝构造函数
        CMyString strTmp(str);

        char *pTmp = strTmp.m_pData;
        strTmp.m_pData = m_pData;
        m_pData = pTmp;
    }

    return *this;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值