Domanda

Sto cercando di creare una funzione di operatore sovrascritta utilizzando entrambi i parametri const, ma non riesco a capire come farlo. Ecco un semplice esempio:

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

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

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

    int value;
}

Quello che sto cercando di fare qui è passare due argomenti nella funzione addizione che sono entrambi const e restituiscono il risultato senza cambiare nulla nella classe:

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

È possibile e come farei per farlo?

Grazie,

Dan

È stato utile?

Soluzione

inline è compreso nelle dichiarazioni di classe, quindi non è necessario specificarlo.

Più idiomaticamente, dovresti rendere operator + una funzione non membro dichiarata al di fuori della definizione della classe, in questo modo:

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

Potrebbe essere necessario renderlo un amico della classe se ha bisogno di accedere agli interni di Number .

Se devi averlo come funzione membro, devi rendere const la funzione stessa:

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

Per classi come Number , operator + è in genere implementato in termini di operator + = poiché di solito si desidera che tutti i soliti operatori lavorino come previsto e operator + = è in genere più facile da implementare e operator + tende a non perdere efficienza rispetto all'implementazione separatamente.

All'interno della classe:

Number& operator+=( const Number& n );

Fuori dalla classe:

Number operator+( const Number& left, const Number& right )
{
    return Number( left ) += right;
}

o anche:

Number operator+( Number left, const Number& right )
{
    return left += right;
}

Altri suggerimenti

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

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

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

    int value;
}

Che ne dici di:

inline Number operator + (const Number& n) const

Mentre ritengo che le risposte precedenti siano abbastanza buone, credo che siano necessari alcuni chiarimenti.

Gli operatori vengono (di solito) in due versioni

Il primo sono le funzioni non membro, il secondo è la funzione membro il cui parametro è l'operando di destra "quot" dell'operazione e che di solito restituisce l'oggetto modificato corrente.

Ad esempio, immagina che ci sia un operatore § per una classe T . Potrebbe essere scritto come funzione non membro :

T operator § (const T & lhs, const T & rhs)
{
   T result ;
   // do the lhs § rhs operation, and puts the result into "result"
   return result ;
}

o come funzione membro :

T & T::operator § (const T & rhs)
{
   // do the "this § rhs" operation, and puts the result into "this"
   return *this ;
}

o addirittura (molto insolitamente) come un'altra funzione membro :

T T::operator § (const T & rhs) const
{
   T result ;
   // do the "this § rhs" operation, and puts the result into "result"
   return result ;
}

Di solito, dovresti preferire la funzione non membro, se non altro perché non dovresti dichiararla amico. Pertanto, l'utilizzo della funzione non amico non membro migliora l'incapsulamento del tuo oggetto.

Disclaimer: ci sono altri aspetti, ma mi sto limitando a operatori aritmetici come + , * , / , - , ecc. qui, così come " credibile " prototipi di operatori.

Analizza il tuo uso dell'operatore

Nel caso di + :

  1. Ogni operando deve essere costante perché a = b + c non deve modificare b , né c .
  2. Puoi accumulare + , come in a = b + c + d + e , quindi i temporali devono esistere.
T & T::operator += (const T & rhs)
{
   // do the "this § rhs" operation, and puts the result into "this"
   return *this ;
}

Nel caso di + = :

  1. Sai che l'operando di sinistra A (da A + = B) verrà modificato.
  2. Sai che l'operando di sinistra A (da A + = B) è il suo risultato.

Quindi dovresti usare:

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

Come sempre, l'ottimizzazione prematura è la radice di tutti i mali

Ho visto questo tipo di codice nel codice di produzione, quindi succede :

<*>

L'autore sperava di economizzare un temporaneo. Con questo tipo di codice, scrivere a = b + c + d porta a risultati interessanti (e sbagliati).

^ _ ^

Ultimo ma non meno importante

Ho scritto un elenco di prototipi di overload degli operatori su questa pagina . La pagina è ancora in costruzione, ma il suo uso principale (facile da copiare / incollare prototipi funzionanti) può essere abbastanza utile ...

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top