c++ - globales - variable static java
datos de clase estáticos frente a espacios de nombres anónimos en C++ (6)
1) Hay una desventaja en la forma de una restricción agregada en la organización binaria. En una presentación en una conferencia de C ++ en la década de 1990, Walter Bright informó que había logrado aumentos significativos 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 Class2 que a otros Class1 :: methods, definir 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, es menos probable que se retrase por un error de página. Este tipo de refactorización es más fácil de emprender con estadísticas de clase que con estadísticas de archivos.
2) Uno de los argumentos en contra de la introducción de la palabra clave del espacio de nombres fue "Puedes hacer lo mismo con una clase", y verás que clase y estructura se usan como espacio de nombres de un hombre pobre en las fuentes de la era anterior al espacio de nombres. El argumento contrario era convincente porque los espacios de nombres se pueden volver a abrir, y cualquier función en cualquier lugar puede formar parte de un espacio de nombres o acceder a un espacio de nombres ajeno, entonces hay cosas que podría hacer con un espacio de nombres que no podría hacer con una clase. Esto tiene relación con su pregunta porque sugiere que el comité de idiomas pensaba que el alcance del espacio de nombres se parece mucho al alcance de la clase; esto reduce la posibilidad de que haya alguna trampa lingüística sutil en el uso de un espacio de nombres anónimo en lugar de una clase estática.
Ocasionalmente tengo clases con miembros privados de datos estáticos. Actualmente estoy debatiendo si debo reemplazar estas variables estáticas en un espacio de nombres sin nombre en el archivo de implementación. Aparte de no poder utilizar estas variables en los métodos en línea, ¿existen otros inconvenientes? La ventaja que veo es que los oculta completamente de los usuarios de la clase.
Estoy de acuerdo en parte con Greg, en que los miembros del espacio de nombres sin nombre no están más encapsulados que los datos privados. El punto de la encapsulación, después de todo, es ocultar los detalles de la implementación de otros módulos, no de otros programadores. Sin embargo, creo que hay algunos casos en los que esta técnica es útil.
Considera una clase como la siguiente:
class Foo {
public:
...
private:
static Bar helper;
};
En este caso, cualquier módulo que quiera usar Foo también debe conocer la definición de Bar, aunque esa definición no tiene relevancia alguna. Este tipo de dependencias de encabezado conducen a reconstrucciones más frecuentes y más largas. Mover la definición de ayudante a un espacio de nombres sin nombre en Foo.cpp es una excelente manera de romper esa dependencia.
También estoy en desacuerdo con la idea de que los espacios de nombres sin nombre son de alguna manera menos legibles o menos fáciles de mantener que los miembros de datos estáticos. Eliminar información irrelevante de su encabezado solo lo hace más conciso.
No estoy convencido de que el beneficio valga el impacto de la legibilidad. En general, considero que algo que es privado es "lo suficientemente oculto".
No estoy de acuerdo con las otras respuestas. Manténgalo lo más alejado posible de la definición de clase.
En la 3ª edición de Scott Meyers, Effective C ++ , recomienda que se prefieran las funciones que no son de amistad a los métodos de clase. De esta manera, la definición de clase es lo más pequeña posible, se accede a los datos privados en la menor cantidad de lugares posibles (encapsulados).
Seguir este principio conduce al lenguaje pimpl . Sin embargo, se necesita equilibrio. Asegúrese de que su código sea mantenible. A ciegas, seguir esta regla lo llevaría a hacer que todos sus archivos de métodos privados sean locales y simplemente pasar los miembros necesarios como parámetros. Esto mejoraría la encapsulación, pero destruiría la mantenibilidad.
Todo lo dicho, archivos de objetos locales son muy difíciles de probar por unidad. Con un poco de piratería inteligente puede acceder a miembros privados durante las pruebas unitarias. Acceder a los objetos locales del archivo es un poco más involved .
No solo los oculta de los usuarios de la clase, sino que los oculta de usted. Si estas variables son parte de la clase, deben estar asociadas con la clase de alguna manera.
Dependiendo de lo que vaya a hacer con ellos, podría considerar convertirlos en variables estáticas dentro de las 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
}
Supongo que se reduce a si estas variables tienen algún significado real en el contexto de la clase (por ejemplo, el puntero a alguna memoria común utilizada por todos los objetos) o simplemente algunos datos temporales que necesita pasar entre los métodos y preferiría no saturar la clase con. En este último caso, definitivamente iría con el espacio de nombres sin nombre. En el primero, diría que es una cuestión de gusto personal.