Substituindo um operador usando const para ambos os parâmetros em C ++
-
03-07-2019 - |
Pergunta
Eu estou tentando criar uma função de operador substituído usando ambos os parâmetros const, mas eu não consigo descobrir como fazê-lo. Aqui está um exemplo simples:
class Number
{
Number()
{
value = 1;
};
inline Number operator + (const Number& n)
{
Number result;
result.value = value + n.value;
return result;
}
int value;
}
O que estou tentando fazer aqui é passar em dois argumentos para a função de adição que são ambos const e retornar o resultado sem mudar nada na classe:
const Number a = Number();
const Number b = Number();
Number c = a + b;
Isso é possível e como eu iria fazer isso?
Obrigado,
Dan
Solução
inline
é entendido em declarações de classe, assim você não precisa especificá-lo.
A maioria idiomaticamente, você faria operator+
uma função não-membro declarada fora da definição de classe, como este:
Number operator+( const Number& left, const Number& right );
Pode ser necessário torná-lo um friend
da classe se ele precisa de acesso a partes internas do Number
.
Se você tem que tê-lo como uma função membro, então você precisa para fazer a função em si const:
Number operator+( const Number& n ) const
{ // ...
Para classes como Number
, operator+
é tipicamente implementado em termos de operator+=
como normalmente você quer todos os operadores habituais para trabalhar como esperado e operator+=
é tipicamente mais fácil de implementar e operator+
tende a não perder qualquer eficiência ao longo implementá-lo separadamente.
Dentro da classe:
Number& operator+=( const Number& n );
Fora da classe:
Number operator+( const Number& left, const Number& right )
{
return Number( left ) += right;
}
ou mesmo:
Number operator+( Number left, const Number& right )
{
return left += right;
}
Outras dicas
class Number
{
Number()
{
value = 1;
};
inline Number operator + (const Number& n) const
{
Number result;
result = value + n.value;
return result;
}
int value;
}
Como sobre: ??
inline Number operator + (const Number& n) const
Enquanto eu sentir as respostas anteriores são bons o suficiente, eu acredito que é necessário algum esclarecimento.
Operadores vêm (geralmente) em dois sabores
O primeiro é as funções de terceiros, sendo a segunda função de membro cujo parâmetro é o "operando direito" da operação e que normalmente retorna o atual modificado objeto.
Por exemplo, imagine que há um §
operador para um T
classe. Pode ser por escrito ou como um função não-membro :
T operator § (const T & lhs, const T & rhs)
{
T result ;
// do the lhs § rhs operation, and puts the result into "result"
return result ;
}
ou como um função de membro :
T & T::operator § (const T & rhs)
{
// do the "this § rhs" operation, and puts the result into "this"
return *this ;
}
ou mesmo (muito raramente) como outra função de membro :
T T::operator § (const T & rhs) const
{
T result ;
// do the "this § rhs" operation, and puts the result into "result"
return result ;
}
Normalmente, você deve preferir a função não-membro, mesmo porque você não deve declará-lo amigo. Assim, a utilização da função não-amigo não-membro melhorar o encapsulamento de seu objeto.
Disclaimer:. Há outros sabores, mas eu estou me limitar aos operadores aritméticos como +
, *
, /
, -
, etc. aqui, bem como protótipos operador "credíveis"
Analise seu uso do operador
No caso de +
:
- Cada necessidades operando a ser constante, porque
a = b + c
não deve mudarb
, nemc
. - Você pode acumular
+
, como ema = b + c + d + e
, então temporários deve existir.
T operator § (const T & lhs, const T & rhs)
{
T result ;
// do the lhs § rhs operation, and puts the result into "result"
return result ;
}
No caso de +=
:
- Você sabe a esquerda operando A (de A + = B) será modificado.
- Você sabe a esquerda operando A (de A + = B) é o seu próprio resultado.
Assim que você deve usar:
T & T::operator += (const T & rhs)
{
// do the "this § rhs" operation, and puts the result into "this"
return *this ;
}
Como sempre, otimização prematura é a raiz de todo o mal
Eu vi esse tipo de código no código de produção assim, não acontecer:
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 ;
}
O autor espera para economizar um temporário. Com este tipo de código, escrevendo leads a = b + c + d
a resultados interessantes (e errado).
^ _ ^
Por último, mas não menos importante
Eu escrevi uma lista de sobrecarga de operador protótipos em desta página . A página ainda está em construção, mas seu uso principal (fácil de copiar / colar protótipos de trabalho) pode ser bastante útil ...