6

このクラスAがあるとしましょう:

class A
{
public:
   int a;

   A(int b)
   {
      a = b;
   }
};

+オーバーロードを作成して、このように使用できるようにします

A a(1),b(2),c(3),&d;
d = a + b + c;

各オブジェクトのコンテンツを変更せずに。次の論理的なことは、次のように毎回新しいメモリチャンクを割り当てることです。

A &operator+ (const A &b)
{
   A *c = new A(a+b.a);
   return *c;
}

ただし、これにより新しい問題が発生します。中間結果が失われ、メモリリークが発生します。3つのAオブジェクト参照を受け取り、最初の2つの合計を3番目に格納する静的関数を作成することで、この問題を簡単に解決できましたが、+オーバーロードをその方法で発生させる方法が必要であると確信しています。が欲しいです。

したがって、問題は、メモリリークを発生させずにオペランドを変更しない一連の演算子オーバーロードを使用できる方法はありますか?

4

2 に答える 2

10

値渡しを使用して、これを行うことができます。

A operator+ (A other) //pass by value
{
   other.a += a;
   return other;
}

または、メンバーは一般公開されているため、非メンバー関数を次のように作成aできます(むしろそうする必要があります) 。operator+

A operator+(A left, A const &right) 
{
   left.a += right.a;
   return left;
}

最初の引数は値によって受け入れられ、2番目の引数は参照によって受け入れられることに注意してください。このように、関数でローカル変数を宣言する必要はありません。最初のパラメーターを使用できます。結局のところ、それは関数に対してローカルであるため、それを使ってやりたいことは何でもできます。この場合は、関数に追加right.aして返すだけです。


クラスのより良い設計はこれでしょう:(コメントを読んでください)

class A
{
   int a;  //make it private
public:    
   A(int b) : a(b) //use member initialization list
   {
   }
   A& operator+=(A const & other)  //add `+=` overload, as member of the class
   {
      a += other.a;
      return *this;
   }
};

//and make `+` non-member and non-friend 
A operator+(A left, A const & right) 
{
  left += right; //compute this in terms of `+=` which is a member function
  return left;
}
于 2012-04-28T03:15:30.790 に答える
4

内でポインタを使用する必要はありませんoperator+。スタックに中間オブジェクトを割り当てて、それを返すことができます。

A operator+ (const A &b)
{
   A c(a+b.a);
   return c;
}

あるいは単に:

A operator+ (const A &b)
{
   return A(a+b.a);
}

またはさらに簡単:

A operator+ (const A &b)
{
   return a+b.a;
}

これは暗黙的にを呼び出すのでA::A(int)

リターンタイプから参照を削除したことに注意してください。非定数参照をローカルに返すことはできません。

次に、次のように使用します。

A a(1),b(2),c(3),d;
d = a + b + c;

dこれは参照ではなくなったことに注意してください。

于 2012-04-28T03:11:14.020 に答える