Переопределение оператора с использованием const для обоих параметров в C++

StackOverflow https://stackoverflow.com/questions/410924

Вопрос

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

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;

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

Спасибо,

Дэн

Это было полезно?

Решение

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;
}

Другие советы

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

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

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

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

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

^_^

Последний, но тем не менее важный

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top