2011-10-24 9 views
8

Bastante nuevo programador aquí, y una disculpa anticipada para preguntas tontas.¿Una variable que es de solo lectura después de la asignación en tiempo de ejecución?

Tengo una variable int en un programa que utilizo para determinar las longitudes de mis matrices en algunas de mis estructuras. Solía ​​ponerlo en mi encabezado como const int. Ahora, quiero bifurcar mi programa para dar a la variable diferentes valores dependiendo de los argumentos que figuran en, pero mantenerlo solo de lectura después de que lo asigne en tiempo de ejecución.

Algunas ideas que he tenido que hacer esto. ¿Hay una manera preferida?

  1. declarar una const int * en mi cabecera y asignarlo a un const int en mi función principal, pero que parece torpe.
  2. Hazlo simple int en mi función principal.
  3. Pase la variable como un argumento cuando se invoca la función.
  4. Algo más que no he pensado aún.
+0

Si va a utilizar esta variable para crear matrices de tamaño variable en tiempo de ejecución, entonces esto no es estándar C++. El estándar C++ no permite ** matrices de longitud variable (VLA) **. Entonces la longitud de la matriz debe ser una constante de tiempo de compilación. –

+0

@Als: estoy creando arreglos de longitud constante, pero no estoy seguro de cuál es la longitud hasta el tiempo de ejecución. –

+1

@BlueMagister: Entonces no son de longitud constante. "constante" en este contexto significa "constante de tiempo de compilación". No puede dar una matriz (a menos que lo asigne con 'nuevo') un tamaño de tiempo de no compilación en C++.Tienes que usar un 'std :: vector' o asignarlo con' new'. –

Respuesta

9

Yo usaría una función variable estática y una función simple. Observe:

int GetConstValue(int initialValue = 0) 
{ 
    static int theValue = initialValue; 
    return theValue; 
} 

Dado que se trata de una variable estática de nivel de función, se inicializa solo la primera vez. Entonces el parámetro initialValue es inútil después de la primera ejecución de la función. Por lo tanto, todo lo que necesita hacer es asegurarse de que la primera llamada de la función sea la que lo inicializa.

0

Estoy tentado de decir que lo que quiere no tiene sentido. Una constante es algo que no cambia su valor, no es algo que tal vez cambie su valor una o dos veces. Si quieres una variable global, simplemente hazla no constante.

Por otro lado, si tiene valores de constante de ámbito, simplemente los declarará e inicializará al mismo tiempo, siguiendo la guía general de C++ para declarar lo más cerca posible del sitio de uso. Por ejemplo, marcar el uso de constantes en el siguiente ámbito local:

for (auto it = v.begin(), end = v.end(); it != end; ++it) 
{ 
    const Foo & x = *it; 
    const std::size_t n = x.get_number_of_bars(); 

    // use x and n ... 

    const bool res = gobble(x, zip(n)); 
    if (res && shmargle(x)) { return 8; } 
} 

Aquí el compilador puede incluso elegir no generar ningún código especial para las variables en absoluto si su valor es ya conocido a través de otros medios.

+1

Estaba buscando una manera de asignar una variable una vez en el tiempo de ejecución, pero luego la hago inmutable después. –

1

¿Cuándo sabe exactamente el valor correcto? Si lo lee desde un archivo o lo que sea, que pueda decir:

const int n = determine_correct_value(); 
+0

Sé el valor correcto de los argumentos aprobados. Pero esta construcción tiene sentido. Voy a jugar con mi código y ver si esto funciona. –

+2

¿Quiere decir 'argv'? No funcionará entonces, lo siento. Los Globals se inicializan antes de que el flujo de control ingrese 'main'. – fredoverflow

6

C++ no tiene una solución integrada para esto, pero si realmente quiere asegurarse de que su int solamente se asigna una vez , usted puede construir su propia clase especial especial:

class MyConstInt 
{ 
public: 
    MyConstInt(): assigned(false) {} 
    MyConstInt& operator=(int v) 
    { 
     assert(!assigned); 
     value = v; 
     assigned = true; 
     return *this; 
    } 
    operator int() const 
    { 
     assert(assigned); 
     return value; 
    } 
private: 
    int value; 
    bool assigned; 
}; 


MyConstInt mi; 
// int i = mi;   // assertion failure; mi has no value yet 
mi = 42; 
// mi = 43;  // assertion failure; mi already has a value 
int* array = new int[mi]; 
+0

En lugar de un 'MyConstInt' lo haría un' MySettings', pero un concepto similar. Además, construir desde un valor sería una gran idea. –

+0

@Mooing Duck: Es cierto, pero quería mostrar la implementación más simple posible (por ejemplo, la creación de plantillas en el tipo de valor también sería una buena idea). – imre

+0

Creo que es una gran idea también. Mejor que la función con 'static'. ¡Gracias! –

Cuestiones relacionadas