Manipular variables globales

Tengo funciones en dos archivos C ++ (vinculados) que usan la misma variable. Para mí (un principiante completo), pude ver dos formas de manejar esto:

  1. Pasar la variable de la primera función a la segunda (son secuenciales en el programa), o

  2. Defina la variable como un valor global en un archivo de encabezado separado que ambos archivos c ++ incluyen al principio

Si bien (1) puede parecer la respuesta más obvia, elegí usar 2. Por cualquier motivo.

De todos modos, la variable ahora está declarada en el encabezado, pero si trato de asignar un valor a la variable en el momento de la declaración, obtengo el error "(valor) ya definido en main.obj".

El encabezado se incluye al principio de ambos archivos C ++. La variable no se declara en ningún otro lugar, pero se utiliza.

Debe haber una respuesta obvia a esto, pero soy muy nuevo en C ++. Cualquiera que pueda aclarar por qué no puedo asignar un valor a la variable, estaría muy agradecido.

preguntado el 16 de mayo de 11 a las 17:05

4 Respuestas

Si bien puede resolver el problema de cómo usar un global, es mucho mejor si lo evita por completo. Si tiene dos funciones que modifican una sola variable, entonces lo más simple que puede hacer es pasar la variable como argumento a la función:

void foo( type & var );
void bar( type & var );
int main() {
   type t( constructor_argument );   // [1]
   // [2] operate on t before calling the functions
   foo( t );
   // [3] operate some more if needed
   bar( t );
   // [4] t now has been updated by both foo and bar
}

Si no es necesario construir la variable antes de la primera función ([1] no requerido, y [2] no presente), entonces puede tener esa variable como valor de retorno de la función:

type foo(); // create and return the variable
void bar( type& );
int main() {
   type t = foo();
   // [3] operate on t
   bar( t );
   // [4] use the final t
}

Si no necesita actualizar la variable después de llamar a la primera función, y la segunda función en realidad no modifica la variable (solo lee lo que hizo la primera función) y la variable no es necesaria en main después de la segunda ejecución de la función ([4] está vacío), entonces puede cambiar la firma de la segunda función y evitar la variable en main en total:

type foo();
void bar( type );
int main() {
   bar( foo() );
}

Todas y cada una de las soluciones a los diferentes problemas que se muestran aquí son mucho mejores que tener una variable global utilizada por diferentes funciones. Cuando lees el código en main (o cualquiera que sea la función que tenga la lógica) es obvio cómo fluyen los datos de un punto a otro. En el caso de globales, la necesidad de llamar foo antes de llamar bar no es explícito en el código, la dependencia de lo global está oculta a menos que lea las implementaciones de las funciones.

Evite los globales tanto como sea posible, hará que su código sea más fácil de mantener, más fácil de razonar y más fácil de probar.

contestado el 16 de mayo de 11 a las 21:05

contestado el 16 de mayo de 11 a las 21:05

Dado que declara la variable en el encabezado y luego incluye el encabezado en dos archivos separados, termina definiendo la misma variable en dos lugares.
Una posible forma de organizarlos puede ser:

myList.h

class list { ....};  

file1.cpp

#include "myList.h"
list * x ;

file2.cpp

#include "myList.h"
extern list * x;  

contestado el 16 de mayo de 11 a las 21:05

Intenté envolver la declaración de variable con #ifndef y #endif, que no funcionó - CapitánProg

@Matt: Estaba actualizando mientras publicaste el comentario. Compruebe la respuesta actualizada. - Alok Save

Cree una clase con estas dos funciones (podría agregar algunas más) y una variable miembro en ella. El uso de variables globales es generalmente considerado como una mala práctica en C ++.

contestado el 23 de mayo de 17 a las 14:05

El uso de clases solo por el bien de, por ejemplo, el alcance se considera generalmente una mala práctica en OOP. (Pero para ser justos, una clase todavía es probablemente significativa aquí.) - user395760

Ambas funciones usan la misma variable, por lo que parecen métodos de una clase. - Kirill V. Lyadvinsky

Sí, como dije. Tenga en cuenta que, en muchos casos, algunos principiantes quieren compartir el estado a través de una variable global (o miembro de objeto), no es necesario compartir nada si se utilizan parámetros y valores de retorno. Entonces, "usan la misma variable" no significa que "están relacionados como métodos de una clase". - usuario395760

La mejor manera de compartir un estado es usar patrón singleton. - Kirill V. Lyadvinsky

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.