剑指Offer---面试题1---赋值运算符函数



剑指Offer-面试题1
给如下类型添加赋值运算符函数。

class CMyString {
private:
    char* m_pData;

public:
    CMyString(const char* pData = nullptr);
    CMyString(const CMyString& str);
    ~CMyString();
};

1、赋值运算符函数介绍

运算符重载是C++一种形式的多态,允许赋予C++运算符多种含义。

例如我们有一个Time类,包括小时和分钟,平常我们是没法直接让两个Time类相加获取总的小时分钟的。这是我们可以使用对+运算符重载。

未使用重载形式的写法
MyTime.h 头文件

#ifndef MYTIME_H_
#define MYTIME_H_

class Time
{
private:
    int hour;
    int minute;

public:
    Time();
    Time(int h,int m);

    //和另一个类时间相加
    Time Sum(const Time& t) const;
    //输出当前类表示的时间
    void Show();
};
#endif // !MYTIME_H_

MyTime.cpp 头文件方法实现

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

using namespace std;

Time::Time() {
    hour = minute = 0;
}

Time::Time(int h, int m) {
    hour = h;
    minute = m;
}

Time Time::Sum(const Time& t) const {
    Time sum;
    sum.minute = minute + t.minute;
    sum.hour = hour + t.hour + sum.minute / 60;
    sum.minute %= 60;

    return sum;
}


void Time::Show() {
    cout << hour << "  " << minute << endl;
}

main.cpp

#include <iostream>
#include "MyTime.h"
using namespace std;

int main() {
    Time t1(2, 40);
    Time t2(5, 55);

    Time total = t1.Sum(t2);
    total.Show();
    //输出时间 8 35

    getchar();
    return 0;
}

使用重载形式的写法
MyTime.h 头文件

#ifndef MYTIME_H_
#define MYTIME_H_

class Time
{
private:
    int hour;
    int minute;

public:
    Time();
    Time(int h,int m);

    //和另一个类时间相加
    Time operator+(const Time& t) const;
    //输出当前类表示的时间
    void Show();
};
#endif // !MYTIME_H_

MyTime.cpp 头文件方法实现

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

using namespace std;

Time::Time() {
    hour = minute = 0;
}

Time::Time(int h, int m) {
    hour = h;
    minute = m;
}

Time Time::operator+(const Time& t) const
{
    Time sum;
    sum.minute = minute + t.minute;
    sum.hour = hour + t.hour + sum.minute / 60;
    sum.minute %= 60;
    
    return sum;
}


void Time::Show() {
    cout << hour << "  " << minute << endl;
}

main.cpp

#include <iostream>
#include "MyTime.h"
using namespace std;

int main() {
    Time t1(2, 40);
    Time t2(5, 55);

    //这两种写法效果一样
    //Time total = t1.operator+ (t2);
    Time total = t1 + t2;

    total.Show();
    //输出时间 8 35

    getchar();
    return 0;
}

2、题解

//使用&,跟参数+地址符一样,可以节省内存
CMyString& CMyString::operator=(const CMyString& str)
{
    //判断参数str是否是当前对象实例,是就直接返回
    if (this == &str)
        return *this;

    //重新给data赋值
    delete []m_pData;
    m_pData = nullptr;

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

    //如果返回类型为A,则返回当前对象克隆
    //如果返回类型为A&,则返回当前对象本身
    return *this;
}

3、疑问

3.1 常量引用参数

//如果传入的参数不是引用而是实例,那么从形参转实参过程,会调用类的复制构造函数创建一个新类str。这是无意义的消耗。
CMyString& operator=(CMyString str);

//这样可以提高代码效率,并且我们不需要修改str的内容,所以加上const关键字。
CMyString& operator=(const CMyString& str);

3.2 在VS中调用strcpy()函数

在VS中调用strcpy()函数会出现微软的警告,微软修改了原来的函数,改写了之后变得更安全和方便,我们使用新的就好了。(警告会有提示,不记住也么事)

库函数改写例子:
mkdir改写为 _mkdir
fopen”改写为 fopen_s
stricmp改写为 stricmp_s
strcpy改写为strcpy_s

3.3 c++的null和nullptr

二者区别

C++null就是个字面常量0,nullptr则可以转换为void* 再隐式转换为char*

猜你喜欢

转载自www.cnblogs.com/Fflyqaq/p/11871090.html