Vamos a ver, estoy hasta los co...
Quiero hacer lo siguiente:
class unaclase {
static const char *unavar = "Holaaaa";
...
...
}
Pero no va, ¿cómo se haría?
Sin embargo, esto otro SÍ FUNCIONA:
class unaclase {
static const int unavar = 69;
...
...
}
P.D.: Estoy utilizando Borland C++ Builder 5
Las únicas constantes que pueden inicializarse dentro de una clase son las de tipo entero.
Para tener dentro de la clase una constante de cualquier otro tipo lo que tienes que hacer es declararla solamente, e inicializarla explícitamente en el constructor. Por ejemplo:
class CPrueba
{
private:
const char *str;
public:
CPrueba() : str("Hola")
{
}
};
Metaxas
En serio? Que porquería.
Diox, que me rallo.
Lo que dice Metaxas no crea una constante para TODAS las instancias de la clase, sino que cada una tiene esa constante.
No recuerdo que se pudieran inicializar las variables estáticas(de clase) directamente dentro de la definición de la clase, ya probaré si funciona eso con un int.
Para crear una variable estática( de clase), haz ésto:
/* .h */
class CFoo
{
private:
static TipoVariable ms_NombreVariable;
};
/* .cpp */
CFoo::ms_NombreVariable = Valor;
Si no me he explicado muy bien, decidlo, que llego tardeeeeeeeee
Efectivamente, si quieres declarar una constante global a todas las instancias de la clase la declaras como static y la inicializas fuera de la declaración de la clase, pero tienes que indicar también Grugnorr el tipo de la variable que estás inicializando.
Si se trata de un entero puedes inicializarlo dentro:
class CFoo
{
private:
static const char *str;
static const int a = 5;
};
const char* CFoo::str = "Hola";
Metaxas
Vale, ¿pero alguien me puede decir por qué se puede con un int y no con un char *? O sea, ¿alguna razón lógica?
Porque los dos tipos ocupan 4 bytes.
...mi no entender :o
Pues la razón exacta no la sé, el caso es que está hecho así ;-). Al menos eso es lo que dice el standard ANSI C++ (9.4.2.4):
"If a static data member is of const integral or const enumeration type, its declaration in the class definition can specify a constant-initializer which shall be an integral constant expression (_expr.const_). In that case, the member can appear in integral constant expressions within its scope. The member shall still be defined in a namespace scope if it is used in the program and the namespace scope definition shall not contain an initializer."
Metaxas
Cada vez que instancias una clase se le reserva un espacio concreto para sus variables locales de forma dinámica y por tanto el apuntador a char que estás declarando en la definición de la clase sí se encuentra en una dirección fija en memoria. Pero sin embargo su contenido sería distinto para cada instancia de la clase porque la cadena en sí debe pertencer al espacio de variables de la instancia y por tanto el apuntador que habría que asignar a tu const char* también sería distinto para cada instancia, con lo cuál no tiene mucho de static... En el caso de ints, floats, etc... el inicializador siempre es el número que has puesto en cambio. El problema supongo que está en que el compilador adivinar la posición de memoria donde caerá la cadena...
Mucho ánimo ^_^'
Sync
PD: Hay que tomar drogas para entenderlo, ya lo sé :-?
PPD: Que me corrija cualquier programador de compiladores si me equivoco, no estoy seguro del todo de lo que acabo de decir :loco:
PPPD: Pero mola ¿a que sí? :P
class unaclase {
static const char *unavar = (char *)0x12345;
...
...
}
¿Y esto? ¿Por qué tampoco funciona? Le estoy dando un valor al puntero.
Da igual que exista o no algo en esa dirección mientras no lo use. Un valor es un valor, ¿no?
:llorando:
Bueno, si estamos hablando que no se puede inicializar un char dentro de una clase, eso es un char ¿no? pues eso.
Ya, la cosa está en la razón, en si tiene lógica o no.
Poderse ya he visto que no :(
No funciona porque el compilador directamente pasa de ello, el lenguaje no lo permite, así de simple. El analizador sintáctico está esperando esto:
STATIC CONST TYPE var_name;
o si es un puntero:
STATIC CONST TYPE TOKEN(*) var_name;
y esto otro si se quiere inicializar un entero:
STATIC CONST INT var_name TOKEN(=) const_value TOKEN(;)
cualquier otra cosa lo hará petar.
Las variables estáticas definidas en una clase (variables de clase), están en un espacio de memoria único, que será compartido por todas las instancias de la clase. Respecto a lo que dices, synchrnzr, la cadena de texto también tiene que estar en memoria en un solo sitio, el compilador debería ser lo suficientemente listo para darse cuenta de que es un valor al que está apuntando una variable estática, da igual que se inicialice fuera de la clase o dentro, no hay ningún problema técnico (de hecho, en Java lo puedes hacer), simplemente que el estandar ANSI C++ está definido así. Al igual que no se puedan inicializar los floats dentro, como los ints, ¿por qué?, pues porque al Stroustroup le dio por hacerlo así :-)
Metaxas
Hola, la razón como dice metaxas es que el lenguaje esta definido asi.
Por una parte una "variable" int tal que asi:
static const int n = 5;
esto último el compilador lo trata como si fuera un simple enum. En realidad no es una variable con la que trabajar.
Y esto es asi porque el C++ en sus clases quiere que las variables de un objeto se inicialicen "en su sitio". Me explico, quieren que inicialicemos estas mediante un constructor.
La solución más elegante para este tipo de cosas seria tener por una lado una clase(podria ser la misma) con estos datos y otra que la declare como static dentro de ella:
class String {
char *p;
String():p("hola) { };
};
class unaclase {
static String str;
..........
};
Con esto el objeto str(en particular) lo tenemos solo una vez para todas las instancias de "unaclase".
Un saludo a todos
PD: El señor Bjarne Stroustrup sabia lo que hacia :)