C/C++面试题—实现MyString类

题目介绍

C++岗位面试题:实现自定义MyString类,实现拷贝构造函数和 []、=、+、== 、!=、<< 、>> 运算符重载函数。
自定义MyString估计是C++岗位常考的题目吧,能够较好的验证面试者对C++基础知识掌握的是否牢固。值得每个C++程序员注意的时,如果参数有传递引用,一定要有非空验证,因为引用帮我们封装了指针,MyString *pStr = nullptr; 将*pstr传递给引用参数是不会报错的,但是程序运行会崩溃的!
下面是笔者的写法。

MyString.h

#pragma once
#include <cstdlib>
#include <iostream>
using namespace std;
class MyString
{
public:
    MyString(const char* pData = nullptr);
    MyString(const MyString& otherStr);
    ~MyString();

    MyString& operator=(const MyString& otherStr);
    MyString& operator=(const char* pData);

    char& operator[](unsigned int index);

    MyString operator+(const MyString &str);
    MyString operator+(const char* pData);

    bool operator==(const MyString &str);
    bool operator==(const char* pData);

    bool operator!=(const MyString &str);
    bool operator!=(const char* pData);

    friend ostream& operator<<(ostream& cout, const MyString& str);
    friend istream& operator>>(istream& cin, MyString& str);


private:
    char* m_pData;
    int m_size;
    int m_capacity;
};
ostream& operator<<(ostream& cout, const MyString& str);

istream & operator >> (istream & cin, MyString & str);

MyString.cpp

#include "01MyString.h"

/* 普通构造函数 */
MyString::MyString(const char * pData)
{
    if (nullptr == pData)
    {
        m_size = 0;
        m_capacity = 100;
        m_pData = new char[m_capacity]{ 0 };
        return;
    }
    m_size = strlen(pData);
    m_capacity = 2 * m_size + 1;    //开辟2倍大空间,方便后续存储
    m_pData = new char[m_capacity]{ 0 };
    strcpy(m_pData, pData);
}
/* 拷贝构造函数 */
MyString::MyString(const MyString & otherStr)   
{
    if (nullptr == &otherStr)   //参数传递引用时一定要做非空验证
    {
        m_size = 0;
        m_capacity = 100;
        m_pData = new char[m_capacity] { 0 };
        return;
    }
    m_size = otherStr.m_size;
    m_capacity = otherStr.m_capacity;
    m_pData = new char[m_capacity]{ 0 };
    strcpy(m_pData, otherStr.m_pData);
}

/* 析构函数 */
MyString::~MyString()
{
    if(nullptr != m_pData)
        delete[] m_pData;
}

MyString & MyString::operator=(const MyString & otherStr)
{
    if (this != &otherStr)          //剑指offer写法
    {
        MyString tmpStr(otherStr);  //调用拷贝构造,交换字符串指针
        char* p = tmpStr.m_pData;
        tmpStr.m_pData = m_pData;
        m_pData = p;
    }
    return *this;
}

MyString & MyString::operator=(const char * pData)
{
    MyString tmpStr(pData); //调用构造函数
    char* p = tmpStr.m_pData;
    tmpStr.m_pData = m_pData;
    m_pData = p;
    return *this;
}

/* 返回新对象 */
MyString MyString::operator+(const MyString & str)
{
    if (nullptr == &str)
    {
        return MyString(*this);
    }
    int newSize = m_size + str.m_size + 1;
    char* temp = new char[newSize] {0};
    strcat(temp, m_pData);
    strcat(temp, str.m_pData);
    MyString res(temp);
    delete[] temp;

    return res;
}
/* 返回新对象 */
MyString MyString::operator+(const char * pData)
{
    if (nullptr == pData)
    {
        return MyString(pData);
    }
    int newSize = m_size + strlen(pData) + 1;
    char* temp = new char[newSize] {0};
    strcat(temp, m_pData);
    strcat(temp, pData);
    MyString res(temp);
    delete[] temp;

    return res;
}

char & MyString::operator[](unsigned int index)
{
    return m_pData[index];
}

bool MyString::operator==(const MyString & str)
{
    bool res = false;
    if (nullptr == &str)
        res = false;
    if (this == &str)
        res = true;
    if (strcmp(m_pData, str.m_pData) == 0)
        res = true;
    return res;
}

bool MyString::operator==(const char * pData)
{
    bool res = false;
    if (nullptr == pData)
        res = false;
    if (strcmp(m_pData, pData) == 0)
        res = true;
    return res;
}

bool MyString::operator!=(const MyString & str)
{
    return !operator==(str);
}

bool MyString::operator!=(const char * pData)
{
    return !operator==(pData);
}

ostream& operator<<(ostream& cout, const MyString& str)
{
    if (nullptr == &str)
        return cout;
    cout << str.m_pData;
    return cout;
}

inline istream & operator >> (istream & cin, MyString & str)
{
    if (nullptr == &str)
        return cin;
    memset(str.m_pData, 0, str.m_capacity); //清空数据
    cin >> str.m_pData;
    return cin;
}

int main(int argc, char *argv[])
{
    //测试 构造函数 拷贝构造函数
    MyString name = "Laymond";
    MyString copyName = name;
    cout << name << " " << copyName << endl;
    //测试 [] 运算符
    copyName[0] = 'A';
    cout << copyName << endl;
    //测试 + = 运算符
    copyName = name + " is " + "good !";
    cout << copyName << endl;

    //测试<< >> == != 运算符
    MyString str1, str2;
    cin >> str1 >> str2;
    cout << "str1:"<<str1 << endl;
    cout << "str2:"<<str2 << endl;
    cout << (MyString("hello") == "hello") << endl;
    cout << (MyString("hello") != MyString("hello")) << endl;
    cout << (MyString("hello") == MyString("hello")) << endl;

    //在参数中引用的地方,一定要做非空验证,比如说如下,如果拷贝构造函数 没有做非空验证 程序会崩溃
    MyString *pStr = NULL;
    MyString str(*pStr);

    return 0;
}

运行检测

这里写图片描述

猜你喜欢

转载自blog.csdn.net/qq_29542611/article/details/80376313