1

我有一个测试类来制作我自己的字符串函数。我对复制析构函数有疑问。

我有 2 个字符串:s1 和 s2。我调用函数 s3 = s1 + s2;

它首先调用 operator+ 函数,完成后调用析构函数。因此,operator= 函数中的字符串对象为空。我怎样才能解决这个问题?

析构函数:

String::~String() {
  if (this->str)
    delete[] str;
  str = NULL;
  len = 0;
}

复制构造函数:

String::String(const String& string) {
  this->len = string.len;
  if(string.str) {
    this->str = new char[string.len+1];
    strcpy(this->str,string.str);
  } else {
    this->str = 0;
  }
}

operator=

String & String::operator= (const String& string) {
  if(this == & string)
    return *this;

  delete [] str;

  this->len = string.len;

  if(string.str) {
    this->str = new char[this->len];
    strcpy(this->str,string.str);
  } else {
    this->str = 0;      
  }

  return *this;
}

operator+

String& operator+(const String& string1 ,const String& string2)
{
  String s;

  s.len = string1.len + string2.len;
  s.str = new char[string1.len + string2.len+1];
  strcpy(s.str,string1.str);
  strcat(s.str,string2.str);

  return  s;
}
4

3 回答 3

7

operator+不应通过引用返回局部变量。

将返回类型更改operator+String。即,制作签名:

String operator+( String const& lhs, String const& rhs )

您可能还想为您的String类编写一个“移动构造函数”:String( String&& other )如果您使用 C++11 编写代码。

一个简单的移动构造函数:

String::String( String&& other ): len(other.len), str(other.str) {
  other.len = 0;
  other.str = nullptr;
}

这不是必需的,因为您的 return 语句中的副本operator+可能会在非平凡的优化级别下被编译器“删除”,但仍然是一种很好的做法。

于 2013-04-23T19:05:08.187 回答
3

它正在调用析构函数,因为String s它超出了 operator+ 重载的范围。您的 operator+ 重载需要返回副本而不是引用。

因此,您应该将您的 operator+ 更改为

String operator+(const String& string1, const String& string2)
于 2013-04-23T19:05:55.313 回答
0

是的,我有你的问题

问题是,当您从 + 运算符函数返回对临时对象的引用,然后将其分配给 main 中的其他对象时,因此在这里调用 = 重载函数,您将向其中传递对不再存在的对象的引用

因此,您可以从 + 运算符函数返回一个副本

或者

您可以在 = overlaoded 函数中传递一个副本

于 2013-04-23T19:09:15.470 回答