Переопределение оператора с использованием const для обоих параметров в C ++ - PullRequest
0 голосов
/ 04 января 2009

Я пытаюсь создать переопределенную операторную функцию, используя оба параметра const, но я не могу понять, как это сделать. Вот простой пример:

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

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

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

    int value;
}

То, что я пытаюсь сделать здесь, это передать два аргумента в функцию сложения, которые оба являются константными, и возвращают результат, ничего не изменяя в классе:

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

Возможно ли это и как мне поступить?

Спасибо

Dan

Ответы [ 4 ]

7 голосов
/ 04 января 2009

inline понимается в объявлениях классов, поэтому вам не нужно указывать его.

В большинстве случаев вы бы сделали operator+ функцией, не являющейся членом, объявленной вне определения класса, например:

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

Возможно, вам понадобится сделать его friend класса, если ему нужен доступ к внутренностям Number.

Если вам нужно, чтобы она была функцией-членом, вам нужно сделать саму функцию постоянной:

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;
}
1 голос
/ 04 января 2009

Хотя я чувствую, что предыдущие ответы достаточно хороши, я считаю, что необходимы некоторые разъяснения.

Операторы приходят (обычно) в двух вариантах

Первая - это функции, не являющиеся членами, вторая - функция-член, параметром которой является «правый операнд» операции и которая обычно возвращает текущий измененный объект.

Например, представьте, что есть оператор § для класса 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 ;
}

Обычно вы предпочитаете функцию, не являющуюся членом, хотя бы потому, что вы не должны объявлять ее другом. Таким образом, использование функции non-member non-friend улучшает инкапсуляцию вашего объекта.

Отказ от ответственности: есть и другие варианты, но я ограничиваю себя арифметическими операторами, такими как +, *, /, - и т. Д., А также оператором "заслуживающий доверия" прототипы.

Проанализируйте ваше использование оператора

В случае +:

  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 приводит к интересным (и неправильным) результатам.

^ _ ^

Последнее, но не менее важное

Я написал список прототипов перегрузки операторов на этой странице . Страница все еще находится в стадии разработки, но ее основное использование (простое копирование / вставка рабочих прототипов) может быть весьма полезным ...

1 голос
/ 04 января 2009

Как насчет:

inline Number operator + (const Number& n) const
1 голос
/ 04 января 2009
class Number
{
    Number()
    {
        value = 1;
    };

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

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

    int value;
}
...