programas ejemplos dev definicion constructores completo comandos basicos avanzados c++ static initialization const

ejemplos - ¿Puedo inicializar un miembro de const estática en tiempo de ejecución en C++?



manual completo de c++ pdf (10)

¿Es posible inicializar un miembro constante estático de mi clase durante el tiempo de ejecución? Esta variable es una constante en todo mi programa, pero quiero enviarla como un argumento de línea de comandos.

//A.h class A { public: static const int T; }; //in main method int main(int argc,char** argv) { //how can I do something like A::T = atoi(argv[1]); }

Si esto no se puede hacer, ¿cuál es el tipo de variable que debo usar? Necesito inicializarlo en tiempo de ejecución, así como conservar la propiedad constante.


Método # 1: Inicialice una variable no constante oculta y proporcione una referencia const a ella (como se muestra por dasblinkenlight):

class A { public: static const int &T; }; static int dummy = 0; const int &A::T = dummy; int main() { dummy = 10; std::cout << A::T << std::endl; }

Demo en vivo

Método # 2: Use un miembro estático no const (como lo muestra R Sahu):

class A { public: static int T; }; int A::T = 0; int main() { A::T = 10; }

Demo en vivo

Método # 3: Declare una variable no constante oculta como un miembro estático privado de su clase y proporcione una referencia de const de miembro estático para interconectarlo. Definir una función de amigo como iniciador:

class A { friend void foo(int); static int dummy; public: static const int &T; }; const int &A::T = A::dummy; int A::dummy = 0; void foo(int val) { A::dummy = val; } int main() { foo(10); std::cout << A::T << std::endl; }

Demo en vivo

Método # 4: Declare una variable no constante oculta como un miembro estático privado de su clase y proporcione una referencia de const de miembro estático para interconectarlo. Defina una función miembro estática como iniciador:

class A { static int dummy; public: static const int &T; static void foo(int val) { A::dummy = val; } }; const int &A::T = A::dummy; int A::dummy = 0; int main() { A::foo(10); std::cout << A::T << std::endl; }

Demo en vivo

Prima:

Si desea inicializar solo una vez, puede cambiar la función auxiliar a:

static void foo(int val) { static bool init = true; if(init) A::dummy = val; init = false; }

Demo en vivo


Hay un truco, pero probablemente deberías evitarlo. Aquí hay un ejemplo básico para ilustrar el principio:

int const& foo(int i) { static const int j = (i == 0 ? throw 0 : i); return j; } int main() { try { int x = foo(0); // oops, we throw } catch(...) {} int x = foo(1); // initialized.. int y = foo(0); // still works.. }

¡Cuidadoso!


Lamento no estar de acuerdo con los comentarios y las respuestas que dicen que no es posible inicializar un símbolo de static const al iniciar el programa en lugar de compilarlo.

En realidad, esto ES posible, y lo usé muchas veces, PERO lo inicializo desde un archivo de configuración. Algo como:

// GetConfig is a function that fetches values from a configuration file const int Param1 = GetConfig("Param1"); const int MyClass::Member1 = GetConfig("MyClass.Member1");

Como puede ver, estas constricciones estáticas no se conocen necesariamente en el momento de la compilación. Se pueden establecer desde el entorno, como un archivo de configuración.

Por otra parte, establecerlos desde argv [], parece muy difícil, si es posible, porque cuando se inicia main (), los símbolos estáticos ya están inicializados.


No puede confiar en los datos producidos después de que su main haya iniciado para la inicialización de variables static , ya que la inicialización estática en la unidad de traducción de main produce antes de que main control, y la inicialización estática en otras unidades de traducción puede ocurrir antes o después de la inicialización estática de la unidad de traducción main en orden no especificado

Sin embargo, puede inicializar una variable oculta no constante y proporcionarle una referencia const , como esta:

struct A { public: // Expose T as a const reference to int static const int& T; }; //in main.cpp // Make a hidden variable for the actual value static int actualT; // Initialize A::T to reference the hidden variable const int& A::T(actualT); int main(int argc,char** argv) { // Set the hidden variable actualT = atoi(argv[1]); // Now the publicly visible variable A::T has the correct value cout << A::T << endl; }

Demo.


No solo no puedes, no debes intentar hacer esto jugando con const_cast. Los miembros constantes estáticos tienen una gran probabilidad de terminar en un segmento de solo lectura, y cualquier intento de modificarlos causará que el programa se bloquee.


No, no puedes hacer eso.

Si esto no se puede hacer, ¿cuál es el tipo de variable que debo usar?

Puede utilizar un miembro no const .

class A { public: static int T; }; int A::T;

Otra opción es hacer que T un miembro privado, hacer de main un amigo para que solo pueda modificar el valor, y luego exponer al miembro a través de una función.

#include <cstdlib> class A { public: static int getT() { return T; } private: static int T; friend int main(int argc, char** argv); }; int A::T; int main(int argc, char** argv) { A::T = std::atoi(argv[1]); return 0; }


No, ya que definió la variable como estática y constante, no puede cambiar su valor. Tendrá que establecer su valor en la definición misma, o mediante un constructor llamado cuando cree un objeto de clase A.


Normalmente tendrá más de un valor de configuración. Así que póngalos en una estructura, y el acceso global normal a ella es constante.

const config* Config; ... main (int argc, char* argv []) { Config= new config (argc, argv); ... }

Puede obtener más sofisticado y tener una función global para devolver la configuración, por lo que el código normal no puede cambiar el puntero, pero es más difícil hacerlo por accidente.

Un archivo de encabezado expone get_config () para que todos lo usen, pero la forma de configurarlo solo es conocida por el código que debe hacerlo.


Utilice un patrón de Singleton aquí. tenga un miembro de datos que le gustaría inicializar en tiempo de ejecución en la clase singleton. Se crea una única instancia y el miembro de datos se inicializa correctamente, no habría más riesgo de sobrescribirlo y alterarlo.

Singleton preservaría la singularidad de sus datos.

Espero que esto ayude.


NO

La semántica de lo que se requiere está mal, y no deberías usar una constante estática para eso.

Una estática es un objeto o tipo integral que tiene una duración de almacenamiento estático y un enlace interno.

Una const es un objeto que no cambia su valor a lo largo de la vida útil de la aplicación, cualquier intento de cambiarlo resulta en UD. ( La gran mayoría de estos casos es un choque bastante bien definido )

Como resultado de esta pregunta, se han propuesto soluciones peligrosas para imitar el comportamiento implícito. En la mayoría de los ejemplos, a static-const-reference se le da una estática de alguna manera oculta que se puede asignar en tiempo de ejecución, por ejemplo, this .

Aparte de las dificultades para mantener dicho código, el problema sigue siendo que la semántica declarada no se aplica realmente.

Por ejemplo, mantener el valor constante a lo largo del tiempo de ejecución de la aplicación puede ser pirateado haciendo const_cast<int &>(A::T) = 42 , que es perfectamente válido, define perfectamente el código ya que el tipo al que se hace referencia no es constante.

Lo que se busca aquí es una clase que permite inicializarse solo una vez en toda la aplicación, tiene vínculos internos y la vida útil de la aplicación.

Así que haz una clase de plantilla que haga eso:

template<typename V> class fixation { bool init = true; V val; public: fixation(V const & v) : init(true), val(v) {} fixation & operator=( fixation arg) { if(init ) { this->val = arg.val; } this->init = false; return *this; } V get() { return val; } }; struct A { static fixation<int> T; };

Cómo manejar el caso que se llama una segunda vez, eso es una decisión de implementación. En este ejemplo el valor es totalmente ignorado. Otros pueden preferir lanzar una excepción, hacer una afirmación, ... etc.