C++中简单字符串的实现

3

我开始在 C++ 中编写一个非常简单的字符串类,以下是代码:

class String
{
public:
    String()
    {
        this->_length = 0;
        this->_size = 0;
        this->_string = NULL;
    }
    String(const char* str)
    {
        this->_length = strlen(str);
        this->_size = this->_length + 1;
        this->_string = new char[this->_size];

        strcpy_s(this->_string, this->_size, str);
    }
    ~String()
    {
        if (this->_string != NULL)
        {
            delete[] this->_string;
            this->_string = NULL;
        }
    }

    String& operator+(const char* str)
    {
        String* temp = new String();

        temp->_length = strlen(str) + strlen(this->_string);
        temp->_size = temp->_length + 1;
        temp->_string = new char[temp->_size];

        strcpy_s(temp->_string, temp->_size, this->_string);
        strcat_s(temp->_string, temp->_size, str);

        return (String&)*temp;
    }

    int Length()
    {
        return this->_length;
    }

private:
    int _size;
    int _length;
    char* _string;
};

您可以看到,我对operator+的实现是完全错误的,实际上存在内存泄漏。 编写operator+=要简单得多,因为我只需将char*与this->_string连接起来并返回*this即可。 我需要帮助实现operator+。
注意:这是作业,所以我不想把解决方案复制粘贴过来,但如果有人能指点一下方向,那就太棒了...
谢谢!
编辑: 我添加了拷贝构造函数:
String(const String& str)
{
    this->_length = str._length;
    this->_size = str._size;
    this->_string = new char[this->_size];
    strcpy_s(this->_string, this->_size, str._string);
}

操作符=和操作符+=:

String& operator=(const String& str)
{
    if (this != &str)
    {
        this->_length = str._length;
        this->_size = str._size;
        this->_string = new char[this->_size];

        strcpy_s(this->_string, this->_size, str._string);
    }

    return *this;
}
String& operator+=(const String& str)
{
    this->_length = this->_length + str._length;
    this->_size = this->_length + 1;

    char* buffer = new char[this->_size];
    strcpy_s(buffer, this->_size, this->_string);
    strcat_s(buffer, this->_size, str._string);

    delete[] this->_string;
    this->_string = buffer;

    return *this;
}

但是还有一些问题,因为如果我像这样运行 while(true) 循环:
while (true)
{
    String a = String("string a");
    String b = a;
    b = "string b";
    b += " string c";
}

该进程使用的内存将不断增加。


5
temp变量无需成为指针,应该声明为自动变量。在这种情况下,也不应该通过引用返回结果。 - David G
1
@0x499602D2,你应该把那个变成一个回答吗? - stardust
请查看此链接 - http://www.daniweb.com/software-development/cpp/threads/410105/overloading-operator-to-concat-string - Bill
4
也需要遵守“三倍法则”。 - Mats Petersson
编写操作符+=并不那么简单。 你不能只是将新字符串连接到旧字符串上。你需要重新分配旧字符串的大小,以容纳结果。 - Vaughn Cato
显示剩余5条评论
2个回答

6
您可以在operator+中重用operator+=
(以下代码假定您有一个operator+=、一个复制构造函数和一个赋值运算符,这在您粘贴的代码中并不是这样的)。
编辑:如Jerry Coffin所建议的,以下操作符不应该是类成员而是自由操作符:
编辑2:为了让编译器更多地进行优化,第一个参数不再是const-reference。
String operator+(String a, String const &b) {
  a += b;
  return a;
}

通过这种方式,您可以更简单地使用 operator+= ,并且可以简单地复制构造函数并在简单的组件上构建复杂的组件。
还有一个要记住的问题:
您必须实现复制构造函数和赋值运算符。否则,编译器会以错误的方式为您生成代码:编译器会生成仅复制内容的代码。因此,它也复制指针,但不为副本分配新内存。然后,您有两个实例引用相同的内存,并且都尝试在未定义行为的析构函数中释放它。

1
但他仍然需要复制构造函数和赋值运算符。 - Sergi0
@Sergi0:是的,他需要......但他必须以任何方式获取它,否则他的实现是错误的(即它将使用自动赋值运算符和复制构造函数,这只会复制指针,从而导致双重释放)。 - mmmmmmmm
而且在使用strlen之前,没有检查NULL是不安全的。 - Sergi0
1
@Sergi0:我不想评估原始问题中粘贴的剩余代码,只想尝试回答问题。 - mmmmmmmm

3

一个简单的实现operator+的方法是基于+=。首先创建左操作数的副本,然后使用+=将右操作数添加到其中,最后返回结果。

还要注意,operator+通常不应该是成员函数--它通常应该是自由函数。基本区别在于,作为成员函数,左操作数必须已经是一个字符串才能起作用。作为自由函数,您的字符串构造函数可以用于转换(例如)字符串字面值。例如,string+"something";将与成员函数一起工作,但"something" + string;则不会。如果将+重载为自由函数,两者都将起作用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接