2010-08-25 21 views
5

En un C++ aplicación multi-hilo con muchas clases, estoy tratando de averiguar cuáles son los métodos para definir una variable globalvariables globales en C++

  1. estilo C, lo definen como global en cualquiera archivo fuente, defínalo como extern en un encabezado que se incluye en las clases que acceden a esta variable.

  2. Escriba una clase Singleton, que contiene estas variables globales y expone los métodos set/get para escribir en la variable.

Mediante el segundo método, se puede controlar el acceso de subprocesos múltiples a través de bloqueos de forma centralizada, en lugar del primer enfoque.

¿Hay más y mejores formas?

+8

Sí, la mejor manera es no usar una. – Puppy

+0

¡Oh, no! Por favor no. –

+1

¿Por qué necesita usar variables globales? Es para sincronizar los hilos, si es así, hay mejores mecanismos por ahí. –

Respuesta

3

Si se puede reducir el alcance de su "variable global" (que normalmente es el caso - ¿Cuántas variables son realmente globales?), Puede convertirlo en un miembro privado de clase estática en la clase propietaria apropiada. Si sus otras clases necesitan verlo (o menos probable, actualizarlo), proporcione accesadores get/put.

3

Definitivamente iré con la clase Singleton. Es la mejor manera de manejar variables "globales" en un entorno OOP multiproceso.

+0

El patrón singleton se complica al tener que lidiar con la posibilidad de que cualquier hilo pueda desencadenar la inicialización del objeto. La mayoría de las implementaciones de singleton permiten que varios subprocesos accedan al singleton de forma simultánea mediante un método de "obtención de referencia", por lo que no solucionan los problemas de sincronización que surgen con el uso del objeto. No veo ninguna razón sólida para que una clase singleton sea La mejor solución. –

1

Si usted debe usar una variable global (¿y por qué usa una?) Recomiendo la segunda manera que describió. La primera forma es la forma en que puede encontrarse con todo tipo de problemas de espacio de nombres.

4

En primer lugar, trate de evitar las variables globales tanto como sea posible. Si solo necesita hacerlo (por ejemplo, este es el caso con cin, cout y cerr), su segundo método es definitivamente la mejor (y más natural) forma de hacerlo.

0

Depende del problema en cuestión.

C-style globals tienen la ventaja de la simplicidad, no es necesario para Singleton :: instance() llamada. Sin embargo, Singleton :: instance() le permite inicializar su estado global en la primera llamada.

Para obtener lo mejor de ambos mundos, utilice los valores globales C-style inicializados con el método del contador Schwarz. http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Nifty_Counter

+0

Mala idea que está mal implementada. –

0

Puede definir un objeto de valor que ajuste una sola implementación con el idioma del mango/cuerpo.

Revise también "Modern C++ Design" de Alexandrescu para debatir sobre las dificultades de implementar singleton en entornos MT y cómo abordarlos.

1

Este problema se puede resolver con un método alternativo muy fácilmente.

C++ resuelve este problema muy fácilmente por su nuevo operador :: llamado operador de resolución de alcance. La sintaxis es la siguiente

:: variable-name; 

Este operador permite acceder a la versión global de un vriable.

0

No patear un caballo muerto, pero, como se mencionó, evitar los globos terráqueos es la mejor solución.Algunas razones se enumeran here. Si una variable global es imprescindible, puede considerar proporcionar una función para acceder a ella para evitar el llamado "fiasco global de inicialización".

1

Uno tiende a preferir el segundo método, porque parece que le da un mejor control, pero puede no resultar muy útil en algunos casos.

En primer lugar, en mi comprensión de la filosofía de OOP, no considero los objetos como colecciones de datos, sino entidades en términos de los cuales, puede representar problemas del mundo real. Así que no considero una buena idea tener una clase para almacenar datos aleatorios. Especialmente cuando los miembros de los datos no están relacionados en gran medida.

En segundo lugar, si está pensando en tener un control central, por ejemplo. tener un solo mutex para acceder a todos los miembros de datos, esto no va a funcionar muy bien para los miembros de datos no relacionados. Va a bloquear muchos subprocesos innecesariamente mientras que los datos que desean no son exactamente los que están protegidos actualmente por el bloqueo.

Así que puede parecer extraño, pero preferiría el primer método.