2009-05-13 11 views
16

Ocasionalmente tengo clases con miembros privados de datos estáticos. Actualmente estoy debatiendo si debería reemplazarlos con variables estáticas en un espacio de nombres sin nombre en el archivo de implementación. Otros que no pueden usar estas variables en los métodos en línea, ¿hay algún otro inconveniente? La ventaja que veo es que los esconde por completo de los usuarios de la clase.datos de clase estáticos frente a espacios de nombres anónimos en C++

Respuesta

4

No estoy convencido de que el beneficio valga la pena el impacto de legibilidad. En general, considero que algo que es privado es "suficientemente oculto".

1

¡No solo los esconde de los usuarios de la clase, sino que también los esconde! Si estas variables son parte de la clase, deberían estar asociadas con la clase de alguna manera.

Dependiendo de lo que se va a hacer con ellos, usted podría considerar haciéndolos variables estáticas dentro de funciones miembro estáticas:

// header file 
class A { 
    public: 
    static void func(); 
}; 


// cpp file 
void A :: func() { 
    static int avar = 0; 
    // do something with avar 
} 
4

1) hay un inconveniente en la forma de una restricción adicional sobre la organización binaria . En una presentación en una conferencia de C++ en la década de 1990, Walter Bright informó que logró un aumento significativo en el rendimiento al organizar su código para que las funciones que se llamaban se encontraran en la misma unidad de compilación. Por ejemplo, si durante la ejecución Class1 :: method1 realizó muchas más llamadas a los métodos de Class2 que a otros métodos Class1 ::, la definición de Class1 :: method1 en class2.cpp significaba que Class1 :: method1 estaría en la misma página de códigos que los métodos estaba llamando y, por lo tanto, era menos probable que se retrasara por un error de página. Este tipo de refactorización es más fácil de realizar con la estática de clase que con la estática de archivo.

2) Uno de los argumentos contra introduciendo la palabra clave espacio de nombres era "Se puede hacer lo mismo con una clase," y verá la clase y estructura se utiliza como espacio de nombres de un hombre pobre en fuentes de la pre -espacio de espacio de nombres El contra argumento convincente era porque los espacios de nombres son reabiertos, y cualquier función en cualquier lugar puede formar parte de un espacio de nombres o acceder a un espacio de nombres extranjero, entonces hay cosas que podrías hacer con un espacio de nombres que no no hacer con una clase . Esto tiene relación con su pregunta porque sugiere que el comité de lenguaje estaba pensando en el alcance del espacio de nombres como muy similar al alcance de la clase; esto reduce la posibilidad de que exista una trampa lingüística sutil al usar un espacio de nombre anónimo en lugar de una clase estática.

+5

Tenga en cuenta que eso fue en los 90 y que los compiladores han avanzado hasta el punto en que cosas como la "optimización de todo el programa" de VC++ funcionan lo suficientemente bien como para que ese tipo de refactorización sea una pérdida de tiempo para los programadores. –

+1

¿Walter Bright ha dicho que este tipo de refactorización ahora es una pérdida de tiempo? Una de las preguntas en esa sesión, que abordaba las inquietudes sobre la mantenibilidad, era "¿quién sino usted podrá hacer tales cosas cuando se jubile?" a lo que Walter respondió las palabras al efecto de "Cuando me retire, los compiladores serán más lentos". –

1

Supongo que se reduce a si estas variables tienen algún significado real en el contexto de la clase (por ejemplo, apunta a alguna memoria común utilizada por todos los objetos) o solo algunos datos temporales que necesita pasar entre los métodos y lo haría más bien no desordenar la clase con. En este último caso, definitivamente iría con el espacio de nombre sin nombre. En el primero, diría que es una cuestión de gusto personal.

2

No estoy de acuerdo con las otras respuestas. Mantenga tanto fuera de la definición de la clase como sea posible.

En Scott Meyers' Effective C++ 3rd edition recomienda preferir las funciones de no amigo a los métodos de clase. De esta forma, la definición de clase es como lo más pequeña posible, se accede a los datos privados en tan pocos lugares como posible (encapsulado).

Siguiendo este principio, lleva al pimpl idiom. Sin embargo, se necesita el saldo . Asegúrate de que tu código sea mantenible. A ciegas, siguiendo esta regla lo llevaría a hacer que todos sus métodos privados archivo local y acaba de pasar en los miembros necesarios como parámetros.Este sería mejorar la encapsulación, pero destruir la capacidad de mantenimiento.

Dicho todo esto, los objetos locales de archivo son muy difíciles de probar por unidad. Con , algunos astutos pirateo pueden acceder a miembros privados durante las pruebas unitarias. Acceder a los objetos locales de archivos es un poco más involved.

1

Estoy de acuerdo en parte con Greg, en que los miembros del espacio de nombre sin nombre no están más encapsulados que los datos privados. El objetivo de la encapsulación, después de todo, es ocultar detalles de implementación de otros módulos, no de otros programadores. Sin embargo, creo que hay algunos casos en que esta es una técnica útil.

Considérese una clase como la siguiente:

class Foo { 
public: 
    ... 
private: 
    static Bar helper; 
}; 

En este caso, cualquier módulo que quiere usar Foo también debe conocer la definición de bar, aunque esa definición no es relevante lo que tan nunca. Este tipo de dependencias de encabezado conduce a reconstrucciones más frecuentes y más largas. Mover la definición de helper a un espacio de nombre sin nombre en Foo.cpp es una excelente manera de romper esa dependencia.

También estoy totalmente en desacuerdo con la noción de que los espacios de nombre no nombrados son de alguna manera menos legibles o menos mantenibles que los miembros de datos estáticos. Eliminar la información irrelevante de su encabezado solo lo hace más conciso.

Cuestiones relacionadas