0

両方の const パラメーターを使用してオーバーライドされた演算子関数を作成しようとしていますが、その方法がわかりません。簡単な例を次に示します。

class Number
{
    Number()
    {
        value = 1;
    };

    inline Number operator + (const Number& n)
    {
        Number result;

        result.value = value + n.value;
        return result;
    }

    int value;
}

私がここでやろうとしているのは、const である 2 つの引数を加算関数に渡し、クラス内で何も変更せずに結果を返すことです。

const Number a = Number();
const Number b = Number();
Number c = a + b;

これは可能ですか、どうすればこれを行うことができますか?

ありがとう、

ダン

4

4 に答える 4

7

inlineクラス宣言で理解されるので、指定する必要はありません。

最も慣用的には、次operator+のように、クラス定義の外で宣言された非メンバー関数を作成します。

Number operator+( const Number& left, const Number& right );

の内部friendにアクセスする必要がある場合は、クラスの にする必要があるかもしれません。Number

メンバー関数として持つ必要がある場合は、関数自体を const にする必要があります。

Number operator+( const Number& n ) const
{ // ...

のようなクラスの場合Numberoperator+は通常operator+=、通常のすべての演算子が期待どおりに機能するoperator+=ように実装され、通常は実装が簡単operator+で、個別に実装するよりも効率が失われる傾向がありません。

クラスの内部:

Number& operator+=( const Number& n );

クラス外:

Number operator+( const Number& left, const Number& right )
{
    return Number( left ) += right;
}

あるいは:

Number operator+( Number left, const Number& right )
{
    return left += right;
}
于 2009-01-04T12:40:10.610 に答える
1
class Number
{
    Number()
    {
        value = 1;
    };

    inline Number operator + (const Number& n) const
    {
        Number result;

        result = value + n.value;
        return result;
    }

    int value;
}
于 2009-01-04T12:37:24.390 に答える
1

どうですか:

inline Number operator + (const Number& n) const
于 2009-01-04T12:38:27.337 に答える
1

以前の回答で十分だと思いますが、明確化が必要だと思います。

オペレーターには (通常) 2 つの種類があります

1 つ目は非メンバ関数で、2 つ目はパラメータが操作の「右側のオペランド」であり、通常は現在変更されているオブジェクトを返すメンバ関数です。

たとえば§、 classの演算子があるとしTます。非メンバー関数のいずれかとして記述できます。

T operator § (const T & lhs, const T & rhs)
{
   T result ;
   // do the lhs § rhs operation, and puts the result into "result"
   return result ;
}

またはメンバー関数として:

T & T::operator § (const T & rhs)
{
   // do the "this § rhs" operation, and puts the result into "this"
   return *this ;
}

または(非常に珍しい)別のメンバー関数としても:

T T::operator § (const T & rhs) const
{
   T result ;
   // do the "this § rhs" operation, and puts the result into "result"
   return result ;
}

通常、フレンドとして宣言してはならないという理由だけで、非メンバー関数を優先する必要があります。したがって、非メンバー非フレンド関数を使用すると、オブジェクトのカプセル化が強化されます。

免責事項: 他の種類もありますが、ここでは 、 、 、 などの算術演算子と、「信頼できる」演算子のプロトタイプに限定し+*/ます-

演算子の使用を分析する

の場合+

  1. a = b + c変更してはならないbため、各オペランドは定数である必要がありcます。
  2. +のようにを累積できるa = b + c + d + eため、一時的なものが存在する必要があります。
T operator § (const T & lhs, const T & rhs)
{
   T result ;
   // do the lhs § rhs operation, and puts the result into "result"
   return result ;
}

の場合+=

  1. 左のオペランド A (A += B から) が変更されることがわかっています。
  2. 左のオペランド A (A += B から) はそれ自体の結果であることがわかります。

したがって、次を使用する必要があります。

T & T::operator += (const T & rhs)
{
   // do the "this § rhs" operation, and puts the result into "this"
   return *this ;
}

いつものように、時期尚早の最適化は諸悪の根源です

私はこの種のコードを本番コードで見たので、実際に起こります:

T & operator + (const T & lhs, const T & rhs)
{
   static T result ; // result is STATIC !!!!
   // do the lhs + rhs operation, and puts the result into "result"
   return result ;
}

著者は、一時的に節約したいと考えていました。この種のコードを書くa = b + c + dと、興味深い (そして間違った) 結果が得られます。

^_^

最後だが大事なことは

私は、このページに演算子のオーバーロード プロトタイプのリストを書きました。このページはまだ作成中ですが、その主な用途 (動作中のプロトタイプを簡単にコピー/貼り付けできる) は非常に便利です...

于 2009-01-04T13:30:10.493 に答える