qué - que es un destructor en c++
¿Cuál es la razón para no tener constructor estático en C++? (5)
¿En qué unidad de traducción se ubicarían los objetos estáticos?
Una vez que tenga en cuenta el hecho de que las estadísticas deben colocarse en una (y solo una) TU, entonces no es "muy difícil" ir al resto del camino y asignarles valores en una función:
// .h
class sample
{
public:
static int some_integer;
static std::vector<std::string> strings;
};
//.cpp
// we''d need this anyway
int sample::some_integer;
std::vector<std::string> sample::strings;
// add this for complex setup
struct sample_init {
sample_init() {
sample::some_integer = 100;
sample::strings.push_back("stack");
sample::strings.push_back("overflow");
}
} x;
Si realmente desea que el código para sample_init
aparezca en la definición de sample
de clase, incluso podría ponerlo allí como una clase anidada. Solo tiene que definir la instancia en el mismo lugar en el que define las estadísticas (y después de que se hayan inicializado a través de sus constructores predeterminados, de lo contrario, por supuesto, no se puede push_back
nada).
C # se inventó 15-20 años después de C ++ y tiene un modelo de compilación completamente diferente. No es tan sorprendente que ofrezca características diferentes y que algunas cosas sean menos simples en C ++ que en C #.
C ++ 0x agrega una función para facilitar la inicialización de vectores con algunos datos, llamados "listas de inicialización"
¿Cuál es la razón para no tener constructor estático en C ++?
Si estuviera permitido, estaríamos inicializando todos los miembros estáticos en él, en un lugar de una manera muy organizada, como:
//illegal C++
class sample
{
public:
static int some_integer;
static std::vector<std::string> strings;
//illegal constructor!
static sample()
{
some_integer = 100;
strings.push_back("stack");
strings.push_back("overflow");
}
};
En ausencia de constructor estático, es muy difícil tener un vector estático y poblarlo con valores, como se muestra arriba. El constructor estático resuelve elegantemente este problema. Podríamos inicializar miembros estáticos de una manera muy organizada.
Entonces, ¿por qué ''C ++ no tiene constructor estático? Después de todo, otros idiomas (por ejemplo, C #) tienen constructor estático!
Estático implica una función que está disociada con un objeto. Dado que solo se construyen objetos, no es evidente por qué un constructor estático tendría algún beneficio.
Siempre puede mantener un objeto en un ámbito estático que se ha construido en un bloque estático, pero el constructor que usaría todavía se declararía como no estático. No hay ninguna regla que indique que no se puede llamar a un método no estático desde un ámbito estático.
Finalmente, C ++ / C define el inicio de un programa cuando se ingresa a la función main
. Los bloques estáticos se llaman antes de la entrada de la función main
como parte de la configuración del "entorno" del código evaluado. Si su entorno exige un control total sobre la configuración y el desmontaje, entonces es fácil argumentar que no es realmente un elemento ambiental, sino un componente de procedimiento hereditario del programa. Sé que el último bit es una especie de código-filosofía (y que su razón podría interpretarse de manera diferente), pero no se debe poner el código crítico "antes" del inicio oficial de la entrega de un ejecutable "control total" al código escrito por el programador.
Esto realmente no tiene sentido para c ++ - las clases no son objetos de primera clase (como en, por ejemplo, java).
Un constructor (estático | cualquier cosa) implica que algo se construye, y las clases de c ++ no se construyen, simplemente lo son.
Sin embargo, puedes lograr fácilmente el mismo efecto:
//.h
struct Foo {
static std::vector<std::string> strings;
};
//.cpp
std::vector<std::string> Foo::strings(createStrings());
OMI, simplemente no hay necesidad de una forma sintáctica más de hacer esto.
Podría pasar por poner a sus miembros "estáticos" en su propia clase con su propio constructor que realice su inicialización:
class StaticData
{
int some_integer;
std::vector<std::string> strings;
public:
StaticData()
{
some_integer = 100;
strings.push_back("stack");
strings.push_back("overflow");
}
}
class sample
{
static StaticData data;
public:
sample()
{
}
};
Se garantiza que su miembro de data
estáticos se inicializará antes de intentar acceder a él por primera vez. (Probablemente antes de main pero no necesariamente)
Usar el problema del orden de inicialización estático como una excusa para no presentar esta característica al lenguaje es y siempre ha sido una cuestión de status quo; no se presentó porque no se presentó y la gente sigue pensando que el orden de inicialización no fue una razón. para introducirlo, incluso si el problema del pedido tiene una solución simple y muy sencilla.
Orden de inicialización, si las personas realmente hubieran querido abordar el problema, habrían tenido una solución muy simple y directa:
//called before main()
int static_main() {
ClassFoo();
ClassBar();
}
Con declaraciones apropiadas:
class ClassFoo {
static int y;
ClassFoo() {
y = 1;
}
}
class ClassBar {
static int x;
ClassBar() {
x = ClassFoo::y+1;
}
}
Entonces, la respuesta es que no hay razón para que no esté allí, al menos no técnica.