Impostazione dei parametri globali: è un uso ragionevole di const_cast e volatile?

2

Ho un programma che eseguo ripetutamente con vari set di parametri. Diversi parametri sono usati in diverse parti del programma (inclusi diversi file sorgente). Lo stesso parametro può essere utilizzato anche in luoghi diversi. Tuttavia, tutti i parametri sono costanti durante l'esecuzione dopo che sono stati impostati.

Ho scoperto molto rapidamente che dichiarare i parametri localmente non ha senso (implica dover ricordare dove ogni parametro è definito, ecc.), quindi ho fatto ricorso a params.h dove ho dichiarato e definito tutti i parametri: const int Param1 = 42; , ecc.

Il lato negativo di questo è che devo ricompilare ogni volta che cambio un parametro. Quindi sto pensando di usare il metodo qui sotto. Si basa sull'utilizzo di volatile e const_cast , che è normalmente considerato "sporco", ma garantisce che una volta che i parametri siano stati impostati in main , non vengano accidentalmente modificati da nessun'altra parte nel programma.

Mi chiedo se le persone pensano che sia OK, perché alla fine voglio aprire il mio codice.

In params.h :

namespace Params
{
extern volatile const int Param1;
// etc.
}

In main.cpp :

#include "params.h"

volatile const int Params::Param1 = 0;

int main(int argc, char* argv[])
{
    int* const pParam1 = const_cast<int*>(Params::Param1);
    *pParam1 = // Get value from argv[] or some config.ini file.
    // etc.
}
    
posta MGA 23.06.2014 - 21:16
fonte

3 risposte

3

Non usare volatile const , sembra un'assurdità! Invece, usa una classe / struct e inizializza tutte le variabili nel costruttore. Puoi ancora usare const.

Params.h:

struct ConfigParams {

    const int param1;
    const int param2;
    // ...

    // Define a constructor that will load stuff from a configuration file.
    // Tune this to meet your needs, such as parsing the data from a startup command line.
    ConfigParams(const std::string & configFileName);
};

// The global that you will use to fetch the configurations during runtime.
extern const ConfigParams configParams;

Params.cpp:

// Declare the global configuration data table:
const ConfigParams configParams("app_configs.ini");

// The constructor:
ConfigParams::ConfigParams(const std::string & configFileName)
    : param1(getConfigFromFile(configFileName, "param1"))
    , param2(getConfigFromFile(configFileName, "param2"))
    // and so on ...
{
}

// And this function would open the file and lookup the requested parameter key, returning its value:
int getConfigFromFile(const std::string & configFileName, const std::string & key)
{
    // TODO...
}
    
risposta data 24.06.2014 - 04:20
fonte
1

Si dovrebbe leggere i parametri da un file di configurazione all'avvio del programma. È possibile passare il nome del file sulla riga di comando. Vedi questa risposta per informazioni su utilizzando boost :: property_tree per leggere un file di parametri.

    
risposta data 23.06.2014 - 21:37
fonte
0

Non è solo irragionevole, è vietato dallo standard modificare una variabile const.

[dcl.type.cv] / 4 dice (enfatizza il mio):

Except that any class member declared mutable (7.1.1) can be modified, any attempt to modify a const object during its lifetime (3.8) results in undefined behavior.

L'idea è ancora buona. Dichiarare una variabile extern e definirla in un file sorgente. Quando hai bisogno di cambiarlo, non hai i file da ricompilare.

Se non vuoi ricompilare, hai diverse opzioni:

  • carica i parametri da un file
  • leggi la variabile d'ambiente
  • passa come parametro al programma
risposta data 24.06.2014 - 13:25
fonte

Leggi altre domande sui tag