Переопределение оператора с использованием const для обоих параметров в C++
-
03-07-2019 - |
Вопрос
Я пытаюсь создать переопределенную операторную функцию, используя оба константных параметра, но не могу понять, как это сделать.Вот простой пример:
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 ;
}
Обычно вам следует отдавать предпочтение функции, не являющейся членом, хотя бы потому, что вам не следует объявлять ее дружественной.Таким образом, использование функции, не являющейся членом и не являющейся другом, улучшает инкапсуляцию вашего объекта.
Отказ от ответственности:Есть и другие варианты, но я ограничиваюсь арифметическими операторами, например +
, *
, /
, -
, и т. д.здесь, а также «заслуживающие доверия» прототипы операторов.
Проанализируйте использование оператора
В случае +
:
- Каждый операнд должен быть постоянным, потому что
a = b + c
не должен менятьсяb
, ниc
. - Вы можете накопить
+
, как в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 ;
}
В случае +=
:
- Вы знаете, что левый операнд A (из A += B) будет изменен.
- Вы знаете, что левый операнд 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
приводит к интересным (и неправильным) результатам.
^_^
Последний, но тем не менее важный
Я написал список прототипов перегрузки операторов на эта страница.Страница все еще находится в разработке, но ее основное использование (простое копирование/вставка рабочих прототипов) может быть весьма полезным...