質問

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

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

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

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

    int value;
}

ここでやろうとしていることは、2つの引数を追加関数に渡すことです。これらは両方ともconstであり、クラス内で何も変更せずに結果を返します。

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

これは可能ですか、これをどのように実行しますか?

ありがとう、

ダン

役に立ちましたか?

解決

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

ほとんどの場合、次のように、 operator + をクラス定義外で宣言された非メンバー関数にします。

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

Number の内部へのアクセスが必要な場合は、クラスの friend にする必要があります。

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

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

Number などのクラスの場合、通常、 operator + 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;
}

他のヒント

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

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

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

    int value;
}

方法:

inline Number operator + (const Number& n) const

前の回答で十分だと感じていますが、いくつかの説明が必要だと思います。

演算子は(通常)2つのフレーバーで提供されます

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

たとえば、クラス 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 & T::operator += (const T & rhs)
{
   // do the "this § rhs" operation, and puts the result into "this"
   return *this ;
}

+ = の場合:

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

次を使用する必要があります:

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 を書くと、興味深い(そして間違った)結果になります。

^ _ ^

最後になりましたが、少なくとも

このページ。このページはまだ作成中ですが、その主な用途(作業中のプロトタイプのコピー/貼り付けが簡単)は非常に便利です...

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top