重写c++中string类,实现基本string功能

来源:互联网 发布:第一届大数据教育论坛 编辑:程序博客网 时间:2024/04/28 20:45

从网上看了一些人贴出来的代码,感觉对于空字符串的判断不够。在测试的时候发现会出现各种问题。下面的代码是我经过测试最终版本,感觉已经差不多了,不知道里面还是否有问题。贴出来,希望大家能够指出来,共同学习,进步。

这个是mystring.h头文件

#ifndef MYSTRING_H_#define MYSTRING_H_#include <iostream>#include <string.h>#define MAXLEN 1000class Mystring{public:    Mystring();    Mystring(const char* str);    Mystring(const Mystring& other);    ~Mystring();    Mystring& operator = (const Mystring& other);    friend Mystring operator + (const Mystring& str1,const Mystring& str2);    friend Mystring operator += (Mystring& str1,const Mystring& str2);    friend std::ostream& operator << (std::ostream& os, const Mystring& mystr);    friend std::istream& operator >> (std::istream& is, Mystring& mystr);    friend bool operator == (const Mystring& str1, const Mystring& str2);    friend bool operator != (const Mystring& str1, const Mystring& str2);    size_t getLen();    bool isEmpty();    //from the start position to find a char or chars    int Find(int start, char ch) const;    //get the substring, if the position is not legal,     //do not do anything to subString    void subStr(Mystring& subString, int pos, size_t size);private:    size_t m_len;    char* m_string;};Mystring::Mystring(){    m_len = 0;    m_string = new char[m_len + 1];    m_string = '\0';}Mystring::Mystring(const char* str){    m_len = strlen(str);    if (m_len > MAXLEN)    {        m_len = MAXLEN;    }    m_string =new char[m_len + 1];    strcpy_s(m_string,m_len + 1,str);}Mystring::Mystring(const Mystring& other): m_string(nullptr), m_len(0){    m_len = other.m_len;    m_string = new char[m_len + 1];    strcpy_s(this->m_string, m_len + 1, other.m_string);}Mystring::~Mystring(){    delete [] m_string;}Mystring& Mystring::operator = (const Mystring& other){    if (this->m_string == other.m_string)    {        return *this;    }    if (this->m_string != nullptr)    {        delete [] this->m_string;    }    this->m_len = other.m_len;    this->m_string = new char[m_len + 1];    strcpy_s(m_string, m_len + 1, other.m_string);    return *this;}//friend function is not belong to class.Mystring operator+(const Mystring& str1,const Mystring& str2){    Mystring tempstr;    if (str1.m_string == nullptr)    {        return tempstr = str2;    }    else if (str2.m_string == nullptr)    {        return tempstr = str1;    }    tempstr.m_len = str1.m_len + str2.m_len;    tempstr.m_string = new char[tempstr.m_len + 1];    strcpy_s(tempstr.m_string, str1.m_len + 1, str1.m_string);    strcat_s(tempstr.m_string, tempstr.m_len + 1, str2.m_string);    return tempstr;}Mystring operator += (Mystring& str1,const Mystring& str2){    str1 = str1 + str2;    return str1;}std::ostream& operator << (std::ostream& os, const Mystring& mystr){    if (mystr.m_string != '\0')    {        os << mystr.m_string;    }    return os;}std::istream& operator >> (std::istream& is, Mystring& mystr){    char temp[MAXLEN],ch;    int templen = 0;    is.getline(temp,MAXLEN);    templen = strlen(temp);    mystr.m_len = templen;    delete [] mystr.m_string;    mystr.m_string = new char[mystr.m_len + 1];    strcpy_s(mystr.m_string,mystr.m_len + 1, temp);    return is;}bool operator == (const Mystring& str1, const Mystring& str2){    if (str1.m_string == nullptr)    {        return !str2.m_string;    }    else if (str2.m_string == nullptr)    {        return false;    }    if (strcmp(str1.m_string,str2.m_string) == 0)    {        return true;    }    return false;}bool operator != (const Mystring& str1, const Mystring& str2){    if (str1.m_string == nullptr)    {        return !str2.m_string;    }    else if (str2.m_string == nullptr)    {        return true;    }    if (strcmp(str1.m_string,str2.m_string) == 0)    {        return true;    }    return false;}size_t Mystring::getLen(){    return this->m_len;}bool Mystring::isEmpty(){    return (this->m_len == 0) ? true: false;}//if we can't find  return negative oneint Mystring::Find(int start, char ch) const{    if (this->m_string == nullptr)    {        return -1;    }    if (start > this->m_len)    {        return -1;    }    char temp[MAXLEN + 1];    strcpy_s(temp,this->m_len + 1, this->m_string);    int i = start;    while (i <= this->m_len && temp[i] != ch)    {        i++;    }    if (i > this->m_len)    {        return -1;    }    else        return i;}void Mystring::subStr(Mystring& subString,int pos, size_t size){    if (this->m_string == nullptr)    {        return;    }    if (pos > this->m_len)    {        return;    }    if ((pos + size) > this->m_len)    {        subString.m_len = this->m_len - pos + 1;    }    else        subString.m_len = size;    subString.m_string = new char[subString.m_len];    int i;    for (i = 0; i < subString.m_len; i++)    {        subString.m_string[i] = this->m_string[i + pos - 1];    }    subString.m_string[i] = '\0';}#endif
上面的代码版本是更新过的,本来想在原来的版面上修改让大家都看到,但是无奈各种混乱排版。干脆重新改写了下。在下面简单的说一下代码的问题.

首先原来我写的operator+()函数代码如下:

Mystring& operator+(const Mystring& str1,const Mystring& str2){    static Mystring tempstr;    if (str1.m_string == nullptr)    {        return tempstr = str2;    }    else if (str2.m_string == nullptr)    {        return tempstr = str1;    }    tempstr.m_len = str1.m_len + str2.m_len;    tempstr.m_string = new char[tempstr.m_len + 1];    strcpy_s(tempstr.m_string, str1.m_len + 1, str1.m_string);    strcat_s(tempstr.m_string, tempstr.m_len + 1, str2.m_string);    return tempstr;}
如此写代码的问题是在于对于函数返回过程的不明确。在str1 = str2 + str3;执行时调用该函数,函数体执行结尾处,在return tempstr语句执行完之后,会发生拷贝tempstr对象给临时变量。而tempstr会随着函数的退出而自动调用析构函数。也就是传给str1的时候,不是tempstr,而是tempstr传递的一个临时对象。其实这个知识之前是知道的,但是由于在代码的其他地方有问题出现错误,我就错误的认为是该函数中定义的tempstr值在传给str1时候,已经析构,造成传值错误。所以将该变量声明为static,并且采用引用来返回,太挫了。

而代码的另外的一个问题就是拷贝构造函数,原来的代码是这样的。

Mystring::Mystring(const Mystring& other){    m_len = other.m_len;    if (m_string != nullptr)    {        delete [] m_string;    }    m_string = new char[m_len + 1];    strcpy_s(this->m_string, m_len + 1, other.m_string);}

而正确的写法是:

Mystring::Mystring(const Mystring& other): m_string(nullptr), m_len(0){    m_len = other.m_len;    m_string = new char[m_len + 1];    strcpy_s(this->m_string, m_len + 1, other.m_string);}
在拷贝构造函数中m_string 是需要初始化为空的,而且没有必要判断m_string是否为空。


再次,感谢@No.机器人的指点。

原创粉丝点击