Autor
|
Tema: Variables estaticas... (Leído 5,105 veces)
|
digimikeh
Desconectado
Mensajes: 191
|
Muy buenas.. Tengo un mal concepto quizá de lo que son las variables estáticas, yo las imagino algo asi como un contenedor que se crea automáticamente al iniciarse un programa, vive durante todo el programa y luego se cierra una vez que el programa termina... como un bolso de viaje que tomas al iniciar el viaje y te deshaces de él cuando regresas a casa... asi es como yo las veo.. (por favor, indicarme si estoy mal). El siguiente código no esta reflejando esto: main.cpp#include <iostream> #include "Archivo2.h" #include "Archivo1.h" int main() { x::num = 10; std::cout << "Desde main -> " << x::num << "Memoria : " << &x::num; std::cout << std::endl; Archivo1 a; a.printVal(); return 0; }
Archivo1.h#pragma once struct Archivo1{ void printVal() const; };
Archivo1.cpp#include "Archivo2.h" #include "Archivo1.h" #include <iostream> void Archivo1::printVal() const { std::cout << "Desde Archivo1 -> " << x::num << "Memoria : " << &x::num; }
Archivo2.hnamespace x{ static int num; }
La salida de consola "Desde Main ->" imprime 10 La salida de consola "Desde Archivo1 ->" imprime 0... Creí que estaba imprimiendo el mismo elemento, pero no, cuando le agregue que imprimiera la dirección de memoria, me encontré con la sorpresa de que ambas estan imprimiendo direcciones diferentes.... En qué momento se creó una nueva instancia de la variable estática y como puedo solucionar este dilema?.. mi intención es escribir e imprimir en una sola variable x::num Saludos_!
|
|
« Última modificación: 29 Agosto 2019, 05:24 am por digimikeh »
|
En línea
|
Dungeons & dragons; dragons.Attack();
|
|
|
@XSStringManolo
Hacker/Programador
Colaborador
Desconectado
Mensajes: 2.399
Turn off the red ligth
|
Prueba añadiendo external antes de static int num; en el archivo2.h
Parece un problema de linkado, que te crea otra static nueva en el .cpp.
|
|
|
En línea
|
Mi perfil de patrocinadores de GitHub está activo! Puedes patrocinarme para apoyar mi trabajo de código abierto 💖
|
|
|
Loretz
Desconectado
Mensajes: 117
|
El contenido de los archivos header (*.h) se copia y pega en cada lugar donde el compilador encuentra su #include. En tu caso se está escribiendo namespace x { inline static int num; } en cada lugar donde se encuentre Así, tendrás una x::num en cada cpp, una inicializada a 10 y la otra a 0 ("zero initialized", como exige el estándar). Pero, además, las variables static tiene un alcance ("scope") a nivel de unidad de traducción (básicamente cada cosa que vaya a compilarse como *.obj), así que es natural que tengas una nueva x::num en cada cpp, esa es su naturaleza. Si quieres que sea la misma, no debería ser static.
|
|
|
En línea
|
|
|
|
digimikeh
Desconectado
Mensajes: 191
|
Gracias por las respuestas... Manolo, te refieres a extern ? Loretz, entonces las variables estáticas se instancian mediante la inclusión de archivos y no de tipos ... es asi?... por ejemplo, lo que has dicho: estoy incluyendo el mismo archivo en dos archivos independientes, serian dos instancias separadas de la variable estatica... sin embargo, si instancio dos tipos Archivo2 en un mismo archivo, ahi si estaria utilizando la misma variable estatica para ambos casos.... ? Suponiendo que tengo una clase llamada Alpha, que tiene un campo publico estático llamado myName, si yo instancio esta clase mas de una vez dentro del mismo archivo fuente, todas las instancias de la clase estarían accediendo a la misma dirección de memoria de myName... Es al menos lo que veo aqui en este ejemplo: https://www.tutorialspoint.com/cplusplus/cpp_static_members.htmSaludos..
|
|
|
En línea
|
Dungeons & dragons; dragons.Attack();
|
|
|
Loretz
Desconectado
Mensajes: 117
|
Loretz, entonces las variables estáticas se instancian mediante la inclusión de archivos y no de tipos ... es asi?... No no. Lo que quise decir es que cualquier cosa que escribas en un archivo.h se va a "pegar" en el archivo.cpp justo ahí donde hayas puesto "#include archivo.h". Es como si el compilador hiciera un "buscar y reemplazar", y ahí donde encuentre "#include archivo.h" lo va a reemplazar por el contenido de ese archivo. Sea lo que sea que haya escrito en ese .h. ... sin embargo, si instancio dos tipos Archivo2 en un mismo archivo, ahi si estaria utilizando la misma variable estatica para ambos casos.... ? Esta parte no la entiendo. Si a lo que te refieres es a si escribes dos veces el mismo #include en un mismo *.cpp, si has puesto la guarda "pragma once" (o las directivas #ifndef ... #define ... #endif) el compilador ignorará la segunda inclusión; y si no la has puesto, tendrás un error al compilar, porque estarías violando la regla "ODR" (one definition rule". (Puedes consultar la definición en https://en.cppreference.com/w/cpp/language/definition) Suponiendo que tengo una clase llamada Alpha, que tiene un campo publico estático llamado myName ... Aquí sí, es como dices y se muestra en el ejemplo que mencionas. Pero en este caso ya no sería una variable static sino un dato miembro declarado static, que es otra cosa. Siguen reglas distintas.
|
|
|
En línea
|
|
|
|
digimikeh
Desconectado
Mensajes: 191
|
La cita 2 está relacionada con la 3... es que no me supe explicar correctamente...lo siento Entonces la solución que tengo es lo que planteaba Manolo std::string con la palabra extern de lo contrario sería usar objetos persistentes pero no creo que esto sea muy elegante....
|
|
|
En línea
|
Dungeons & dragons; dragons.Attack();
|
|
|
Loretz
Desconectado
Mensajes: 117
|
Si lo que necesitas es una misma variable accesible desde distintos cpp, deberías declararla "extern", pero ya no sería posible que fuera "static", porque en este sentido son contradictorias. Por ejemplo: en Archivo1.h#pragma once
struct Archivo1 { void printVal() const; }; en Archivo2.h#pragma once
namespace x { extern int num; // no puede ser static } en Archivo1.cpp#include "Archivo1.h" #include "Archivo2.h" #include <iostream>
void Archivo1::printVal() const { std::cout << "Desde Archivo1 -> " << x::num << " Memoria : " << &x::num << '\n'; } en main.cpp#include <iostream> #include "Archivo2.h" #include "Archivo1.h"
int x::num = 10; // definida aquí o en cualquier otro cpp
int main() { std::cout << "Desde main -> " << x::num << " Memoria : " << &x::num << '\n'; Archivo1 a; a.printVal(); return 0; } Salida:Desde main -> 10 Memoria : 00FBC000 // mismo valor, misma dirección de memoria. Desde Archivo1 -> 10 Memoria : 00FBC000 Al declararla como "extern" le dices al compilador que está definida en algún otro lado, y es conocida en todo el programa, en cualquier cpp donde se incluya su declaración (por medio de #include Archivo2.h). Esto mismo también puede hacerse (a partir de C++17) con Archivo2.h#pragma once
namespace x { inline int num = 10; } Y ya no necesitas definir x::num en ninguno de los cpp.
|
|
|
En línea
|
|
|
|
digimikeh
Desconectado
Mensajes: 191
|
De acuerdo, me parece lógico... Bueno, en este caso he querido usar un int como ejemplo para describir mi duda, en el programa que estoy intentando hacer, lo que quiero usar como variable global es un tipo propio que se inicializa con un constructor. En el constructor de ese tipo propio (que se llama Sesion) se inicializan los campos privados, por lo que ... extern Sesion s;
...estaría inicializando dichos campos automáticamente, aún asi debo volver a definir tal como lo hiciste cuando escribiste esta linea ? : int x::num = 10; // definida aquí o en cualquier otro cpp
O es que al escribir extern Sesion s en realidad no estoy ejecutando el constructor con su inicialización? Saludos! y gracias por las respuestas... han sido de mucha ayuda @std::string Manolo y @Loretz.
|
|
|
En línea
|
Dungeons & dragons; dragons.Attack();
|
|
|
Loretz
Desconectado
Mensajes: 117
|
Para objetos de alguna clase es lo mismo que para tipos nativos, puedes usar las dos formas, declarar el objeto como extern o como inline (mejor). Por ejemplo, usando extern podría ser algo así: Archivo1.h#pragma once #include <string>
extern struct X { X(std::string str) : str(str) {} int num = 10; std::string str; } x; Y en algún cpp Usando inline no necesitas que la definición esté en un cpp #pragma once #include <string>
inline struct X { X(std::string str) : str(str) {} int num = 10; std::string str; } x{"hola"}; Estos son un par de ejemplos de cómo podía hacerse antes y ahora con el estándar C++17, pero hay otras cosas a considerar, probablemente necesites un constructor por defecto, y asignarle valores a tu objeto cuando el programa los conozca, o crear el objeto en la memoria libre (usando un smart pointer, por supuesto), o ... Bueno, ya verás. [EDITO] Ah, me olvidaba O es que al escribir extern Sesion s en realidad no estoy ejecutando el constructor con su inicialización? No, no estás ejecutando el constructor, porque extern Sesion es una declaración no una definición.
|
|
« Última modificación: 30 Agosto 2019, 19:33 pm por Loretz »
|
En línea
|
|
|
|
digimikeh
Desconectado
Mensajes: 191
|
ok, entiendo, pero yo tenía entendido que cuando tu definías algo, estas usando el constructor... o es que extern es la excepción? Alpha.hclass Alpha{ int x; public: Alpha() : x{5}{} //hacer otras cosas }
main.cpp#include "Alpha.h" int main (){ Alpha a; //Nota (a) }
Nota (a) : A pesar de estar declarando un objeto llamado a de tipo Alpha se estaría inicializando el campo privado x y valdría 5... (es asi como yo tengo en mi programa el objeto Sesion inicializa sus campos privados a un string "NA". Sin embargo, acabo de darme cuenta que incializar y definir no son la misma cosa...
|
|
|
En línea
|
Dungeons & dragons; dragons.Attack();
|
|
|
|
Mensajes similares |
|
Asunto |
Iniciado por |
Respuestas |
Vistas |
Último mensaje |
|
|
CMS Páginas estaticas
PHP
|
Kevxfire
|
1
|
3,111
|
8 Julio 2011, 19:46 pm
por Nakp
|
|
|
Problema con declaraciones estáticas
« 1 2 »
.NET (C#, VB.NET, ASP)
|
WHK
|
11
|
6,101
|
12 Julio 2013, 16:06 pm
por Novlucker
|
|
|
(PyQt) Variables estaticas en Python
Scripting
|
F3niX14
|
2
|
3,464
|
29 Septiembre 2013, 19:17 pm
por F3niX14
|
|
|
variables estaticas en main
Programación C/C++
|
fafafa01
|
1
|
1,652
|
13 Diciembre 2016, 05:16 am
por engel lex
|
|
|
Listas Estaticas
Programación C/C++
|
angeljonh
|
1
|
2,062
|
30 Septiembre 2017, 12:37 pm
por ivancea96
|
|