1

独自の文字列関数を作成するためのテスト クラスがあります。コピー デストラクタに問題があります。

s1 と s2 の 2 つの文字列があります。関数 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 )

C++11 でコードを記述している場合は、おそらくStringクラスの「ムーブ コンストラクター」も記述したいと思うでしょう。String( String&& other )

単純な移動コンストラクター:

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 soperator+ オーバーロードで範囲外になるため、デストラクタを呼び出しています。operator+ のオーバーロードは、参照ではなくコピーを返す必要があります。

したがって、operator+ を次のように変更する必要があります。

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

ええ、私はあなたの問題を手に入れました

問題は、 + 演算子関数から一時オブジェクトへの参照を返し、これをメインの他のオブジェクトに割り当てている場合です

したがって、 + 演算子関数からコピーを返すことができます

また

= overlaoded 関数でコピーを渡すことができます

于 2013-04-23T19:09:15.470 に答える