2008-12-23 22 views
5

Consideremos una clase de C++. Al comienzo de la ejecución, quiero leer un conjunto de valores de un archivo XML y asignarlos a 7 de los miembros de datos de esta clase. Esos valores no cambian durante toda la ejecución y tienen que ser compartidos por todos los objetos/instancias de la clase en cuestión. ¿Los miembros de datos estáticos son la forma más elegante de lograr este comportamiento? (Por supuesto, no considero variables globales)¿Debo usar miembros de datos estáticos? (C++)

Respuesta

3

Me parece un buen uso de variables estáticas. Está utilizando estos más como parámetros fijos que variables, y los valores legítimamente necesitan ser compartidos.

3

miembros estáticos funcionarían aquí y son perfectamente aceptables. Otra opción es usar un singleton pattern para la clase que contiene estos miembros para garantizar que se construyan/configuren solo una vez.

5

Como han mencionado otros, el uso de miembros estáticos en este caso parece apropiado. Solo recuerde que no es infalible; algunos de los problemas con los datos globales se aplican a los miembros estáticos:

  • No se puede controlar el orden de inicialización de sus miembros estáticos, lo que necesita para asegurarse de que no hay otras variables globales o estáticas se refieren a estos objetos. Consulte this C++ FAQ Question para obtener más información y también algunos consejos para evitar este problema.
  • Si tiene acceso a estos en un entorno de subprocesos múltiples, debe asegurarse de que los miembros estén completamente inicializados antes de generar hilos.
+0

Los valores se establecen al inicio de la ejecución, por lo que esos problemas no son realmente aplicables aquí. –

+0

David, lo harán una vez que decidas poner un objeto xml como un objeto estático en alguna parte. también el orden de destrucción es relevante también. ver mi respuesta a continuación. –

2

suena como un uso apropiado de miembros de clase estáticos. simplemente no olvides que son realmente variables globales con un espacio de nombres y (quizás) algo de protección. por lo tanto, si existe la posibilidad de que su aplicación algún día pueda desarrollar "entornos" separados o algo que necesite un conjunto de estos globales para cada uno, se habría arrinconado.

según lo sugerido por Rob, considere usar un singleton, que es más fácil de convertir más adelante en algún tipo de variable de entorno administrado.

3

No es un diseño limpio. Los miembros de la clase estática son estado global y global state is bad.

Puede que no le cause problemas si se trata de un proyecto de tamaño pequeño a mediano y no tiene metas altas para las pruebas automáticas, pero ya que pregunta: hay mejores formas.

Un diseño más limpio sería crear una fábrica para la clase y hacer que la fábrica pase sus siete variables a la clase cuando la construye. Es entonces la responsabilidad de la fábrica asegurarse de que todas las instancias compartan los mismos valores.

De esta manera su clase se puede probar y ha separado sus preocupaciones adecuadamente.

PS. Don'tusesingletonseither.

+2

Cada vez que leo "xxx es malo", mi detector de sobresimplificación comienza a parpadear. Al igual que otros carteles, creo que este uso de variables estáticas es perfectamente válido. –

+1

El estado global es principalmente malo si cambia. El estado global sin cambios, que es así, funciona bien. –

+0

Acabo de leer su enlace; dice que los Singleton (y el estado global aproximadamente equivalente) no dañan nada si contienen datos inmutables, que es esto. –

0

Siempre que piense en la capacidad de prueba y tenga otra forma de configurar las variables estáticas además de leer en un archivo, además no confíe en los datos benig sin cambios durante todo el tiempo de ejecución del proceso - usted debe multa.

He descubierto que pensar en escribir pruebas cuando diseña su código lo ayuda a mantener el código bien definido y reutilizable.

1

Sí, los datates estáticos son lo que buscas.Pero debe cuidar el orden de inicialización/destrucción de sus variables estáticas. No hay ningún mecanismo en C++ para garantizar que sus variables estáticas se inicialicen antes de usarlas en las unidades de traducción. Para estar seguro, use lo que se parece al patrón singleton y es bien conocido para solucionar ese problema. Funciona porque:

  1. Todos los objetos estáticos están completamente construidos después de la construcción completa de cualquier instancia de xml_stuff.
  2. El orden de destrucción de objetos estáticos en C++ es exactamente lo contrario de la finalización de su construcción (cuando su constructor finaliza la ejecución).

Código:

class xml_stuff { 
public: 
    xml_stuff() { 
     // 1. touch all members once 
     // => 2. they are created before used 
     // => 3. they are created before the first xml_stuff instance 
     // => 4. they will be destructed after the last xml_stuff instance is 
     //  destructed at program exit. 
     get_member1(); 
     get_member2(); 
     get_member3(); 
     // ... 
    } 

    // the first time their respective function is called, these 
    // objects will be created and references to them are returned. 
    static type1 & get_member1() { static type1 t; return t; } 
    static type2 & get_member2() { static type2 t; return t; } 
    static type1 & get_member3() { static type1 t; return t; } 
    // ... all other 7 members 
}; 

Ahora, los objetos devueltos por xml_stuff :: get_memberN() son válidos todo el tiempo de vida de cualquier instancia xml_stuff, porque cualquiera de ellos fueron construidos antes de cualquier instancia xml_stuff. Al usar miembros de datos estáticos simples, no se puede asegurar, ya que el orden de creación en las unidades de traducción no se define en C++.

2

Al comienzo de la ejecución quiero leer un conjunto de valores de un archivo XML y asignarlos a 7 de los miembros de datos de esta clase. Esos valores no cambian durante toda la ejecución y tienen que ser compartido por todos los objetos/instancias de la clase en cuestión.

La frase en negrita es el kicker aquí. Mientras esa declaración se cumpla, el uso de variables estáticas está bien. ¿Cómo se aplicará esto?

Es difícil. Entonces, si para su uso en este momento la declaración es siempre cierta, adelante. Si quiere ser el mismo de algún futuro desarrollador (o usted) que usa sus clases incorrectamente (como leer otro archivo XML a medio camino en el programa), entonces haga algo como lo que dice Rasmus Farber.

Cuestiones relacionadas