È una cattiva idea usare mutable per i temporari pre-allocati?

0

Supponiamo di avere la seguente classe C ++:

class MyFastMessageEncoder
{
public:
    MyFastMessageEncoder() :
        m_fieldEncoder(ENCODING_STYLE_DEFAULT)
    {
    }

    void set_encoding_style(const EncodingStyle encodingStyle)
    {
        m_fieldEncoder.set_encoding_style(encodingStyle);
    }

    EncodingStyle get_encoding_style() const
    {
        return m_fieldEncoder.get_encoding_style();
    }

    void encode(const UnencodedFieldList &unencodedFieldList, Message &message
    {
        for (UnencodedFieldList::const_iterator it = unencodedFieldList.begin(), end = unencodedFieldList.end(); it != end; ++it)
        {
            m_fieldEncoder.set_raw_data(*it);
            message.add_field(m_fieldEncoder.encode());
        }
    }

private:
    FieldEncoder    m_fieldEncoder;
};

La classe MyFastMessageEncoder deve essere estremamente efficiente (la codifica verrà eseguita su decine di migliaia di messaggi al secondo), il tempo necessario per creare un'istanza dell'oggetto FieldEncoder è un costo non trascurabile, quindi per risolvere il problema problema, ho definito l'oggetto FieldEncoder come membro della classe e l'ho inizializzato all'interno del costruttore solo una volta.

Il mio problema è che FieldEncoder::SetRawData() è un metodo non const, il che significa che anche il metodo MyFastMessageEncoder::encode deve essere non-const. Tuttavia , se dovessi rendere temporaneo l'oggetto FieldEncoder nel metodo, MyFastMessageEncoder::encode potrebbe essere contrassegnato come const. Ciò significa che ogni oggetto che chiama MyFastMessageEncoder::encode è anche non-const, che (per me) inizia a rovinare la correttezza del programma.

Ora capisco come funziona la parola chiave mutable e come potrei usarlo per risolvere questo problema, ma la mia domanda è: Lo farebbe essere considerato una cattiva forma, dal momento che gli interni dell'oggetto sono tecnicamente in fase di modifica?

Altre considerazioni:

  • La sicurezza del thread non è un problema, è garantito che venga eseguito solo in un singolo thread (sebbene MyFastMessageEncoder possa essere creato su più thread)
  • Il metodo set_raw_data non influisce sulla classe FieldEncoder al di fuori del metodo MyFastMessageEncoder::encode . Tutti i dati impostati vengono cancellati o sovrascritti la volta successiva che viene chiamato il metodo set_raw_data .
posta Karl Nicoll 23.07.2014 - 23:51
fonte

1 risposta

1

Se la codifica dipende dai campi precedenti, quindi MyFastMessageEncoder::encode è ovviamente non-const in quanto cambia lo stato osservabile dell'istanza - chiamarla due volte non darà lo stesso risultato, quindi lo stato dell'istanza è cambiato, quindi dovrebbe essere non const.

Altrimenti sembra un po 'strano che tu abbia, nel FieldEncoder , un'inizializzazione costosa e che lo stato che segue set_raw_data sia governato solo dai dati impostati. Questo mi suggerisce che il costo di inizializzazione potrebbe essere ridotto - o condividendo alcune delle strutture che sono state impostate, o mettendo in comune gli encoder.

Tuttavia, entrambi questi refactoring sarebbero molto più complicati rispetto al rendere mutevole il codificatore, quindi se il costo di inizializzazione non causa problemi altrove, vorrei commentare che l'encoder esiste solo come membro come ottimizzazione per encode e fare è mutabile.

    
risposta data 24.07.2014 - 00:38
fonte

Leggi altre domande sui tag