1

我自己写字符串类。我重载了 + 运算符。它的工作正常,但后来我试图 eguate cstr = str +pop ,它什么也没做。`您可以在 main() 函数中看到我的错误。编译器没有给出任何错误。

#include <iostream>
#include <string.h>
#include <stdlib.h>

using namespace std;

class S {

public:
          S();
          S(const char *str);
          S(const S &s);

         ~S() { delete []string;}
          S  &operator  =(const S   &s);

          int  lenght() const {return l     ;}
      char*  strS() const {return string;}

      friend ostream &operator <<(ostream &, const S &first) {cout<<first.string;}
      friend S    operator+ (const S& first, const S& second);

private:
          char *string;
          int l;

};

int main(){
S pop("Q6");
S str("M5");

S cstr = str +pop; // works correct
cout<<str;

str = str + pop;
cout<<str ;        // doesnt work, it doesnt write in terminal

return 0;
}
S::S()
{
    l = 0;
    string = new char[1];
    string[0]='\0';
}

S::S(const char *str)
{
    l      = strlen(str);
    string = new   char[l+1];
    memcpy(string, str, l+1);
}

S::S(const S &s)
{
     l = s.l;
     string = new char[l+1];
     memcpy(string,s.string,l+1);
}

S &S::operator=(const S &s)
{
    if (this != &s)
    {
        delete []string;
        string = new char[s.l+1];
        memcpy(string,s.string,s.l+1);
        return *this;
    }
    return *this;
}

S    operator +(const S& first, const S& second)

{
    S temp;
    temp.string = strcat(first.strS(),second.strS());
    temp.l      = first.lenght() + second.lenght();

  return temp;
 }

我期待着你的帮助。

4

5 回答 5

3

您的运营商有错误!

S temp;
//^^^^ has only one byte buffer!!!
temp.string = strcat(first.strS(),second.strS());
//   1 byte   ^^^^^ strcat appends second.strS to first.strS

您应该为 temp 重新分配内存:

S temp;
temp.l      = first.lenght() + second.lenght();
delete [] temp.string; // !!!! - 
temp.string = new char[temp.l + 1]; // !!!!
// you should have another c-tor which can allocate memory!!!
// like: S(unsigned length, unsigned char c = '\0') 
strcpy(temp.string, first.strS());
strcat(temp.string, second.strS());

除了这个明显的错误 -std::bad_alloc例如,您还应该注意异常。查看复制和交换习语以获得更好的方法来完成此任务。

于 2012-10-12T13:02:44.730 回答
2

strcat 的手册页

 The strcat() and strncat() functions append a copy of the null-terminated
 string s2 to the end of the null-terminated string s1, then add a termi-
 nating `\0'.  The string s1 must have sufficient space to hold the
 result.

您正在使用它,就好像它为新的 char 数组分配空间,然后填充它。但是,它不会那样做。

于 2012-10-12T13:02:57.547 回答
1

问题是您operator+没有为组合字符串分配任何内存。它也不会将字符串复制到正确的位置(它将字符串复制到第一个,而不是临时)。您拥有的类设计没有简单的解决方法。

于 2012-10-12T13:04:04.863 回答
0

问题在于您的operator+. strcat()将第二个参数指向的字符串附加到第一个参数指向的字符串。返回值是第一个参数。因此,从operator+结果返回时S,第一个S参数将指向同一个缓冲区。以后会被删两次。。。

于 2012-10-12T13:03:51.413 回答
0

检查 的描述strcat。它将第二个参数附加到第一个参数,假设两者都是以空结尾的字符串,并返回第一个参数。在你的情况下:

  • 它附加到stringfirst 的成员,尽管它没有足够的内存(未定义的行为),并且

  • 它将string指针 in设置为指向与 intemp相同的内存first;第一个被破坏的,另一个指向已删除的内存,并且在默认构造函数中分配的内存temp被泄露。

此外,你永远不会用 终止你的字符串'\0',所以strcat几乎可以做任何事情。

更好的解决方案是首先实施+=,然后+根据它进行定义。 +=将不得不增加它所拥有的内存,并将第二个字符串中的文本附加到它。

当我在做的时候:你的operator=也不行。new 如果失败(抛出std::bad_alloc),它将使对象处于无法破坏的状态。您必须确保所有可能失败的操作都发生delete. (您需要测试自赋值的事实是一个警告信号。在正确编写的赋值运算符中,这种测试很少需要。)在这种情况下,交换习语可能是您最好的选择:复制构造 a newS在局部变量中,然后交换它们的成员。

于 2012-10-12T13:12:26.307 回答