c++ - significado - que es declaracion de variables
Verificar la definiciĆ³n del valor en C++ (9)
¿Por qué no mantener un indicador separado que se inicializa en falso y luego se establece en verdadero cuando se calcula la barra? Luego puede ser ''indefinido'' al establecer la bandera en falso nuevamente.
if(!isBarValid)
{
calculateBar();
isBarValid = true;
}
return bar;
Estoy trabajando en C ++ y necesito saber si un valor escalar (por ejemplo, un double
) está "definido" o no. También necesito poder "descifrarlo" si es necesario:
class Foo {
public:
double get_bar();
private:
double bar;
void calculate_bar() {
bar = something();
}
};
double Foo::get_bar() {
if ( undefined(bar) )
calculate_bar();
return bar;
}
¿Es posible en C ++?
Gracias
C ++ no tiene un estado "indefinido" para los tipos primitivos. El más cercano disponible para flotación / doble sería NAN, pero eso realmente tiene un significado diferente.
Como dicen las otras respuestas, C ++ no tiene este concepto. Sin embargo, puedes evitarlo fácilmente.
O puede tener un valor indefinido al que inicializa la barra en el constructor, generalmente -1.0 o algo similar.
Si sabe que calculate_bar nunca devuelve valores negativos, puede implementar la función indefinida como comprobación de <0.0.
Una solución más general es tener un bool que diga si la barra aún está definida como inicializada como falsa en el constructor y cuando la configura por primera vez, la cambie a verdadera. boost :: optional hace esto de una manera elegante con plantillas.
Este es el aspecto del código que tiene.
class Foo {
public:
double get_bar();
Foo() : barDefined(false) {}
private:
double bar;
bool barDefined;
void calculate_bar() {
bar = something();
}
};
double Foo::get_bar() {
if ( barDefined == false ) {
calculate_bar();
barDefined = true;
}
return bar;
}
Como otros señalaron, no hay nada como un estado "indefinido". Pero es posible que desee examinar boost.optional
Debe hacerlo usando un booleano extra.
Para implementar el uso de un valor booleano adicional, puede probar la lógica como la siguiente plantilla:
template<typename T>
struct Defined
{
bool defined;
T value;
Defined() : defined(false) {}
Defined(const T& value_) : defined(true), value(value_) {}
... and perhaps other operators here ...
... to make this behave even more like a T ...
};
Esto no es posible en C / C ++, las primitivas siempre tienen un valor asignado (principalmente basura, lo que sea que haya en ese punto en la memoria anterior a ella, a menos que se haya asignado explícitamente en la declaración). Es común tener un valor de marcador de posición (es decir, 0 para los punteros) que denota no utilizado, sin embargo, estos también deben asignarse explícitamente. Si su doble puede tomar cualquier valor, entonces le sugiero que coloque un booleano al lado, inicialmente asignado a falso, y pruebe / configure ese cuando desee hacer su cálculo.
Puedes probar Construir en el idioma de primer uso y escribir get_bar()
esta manera:
double & get_bar()
{
static double *bar = new double(something());
return *bar;
}
Cuando llames a get_bar()
, hará bar
para ti si nadie lo ha solicitado todavía. Cualquier llamada posterior simplemente devolverá la bar
. Como dice la página vinculada, esto técnicamente no daña la memoria porque el sistema operativo la reclamará cuando el programa salga.
ACTUALIZAR:
Cambió el valor de retorno a double &
para permitirle modificar la bar
.
Si quiere decir en tiempo de ejecución, no existe tal cosa. Si la bar
nunca se inicializa, tendrá los bits aleatorios allí, dependiendo de cómo se asigne el objeto (algunos asignadores inicializarán la nueva memoria a cero).
editar: depende del programador manejar el estado del objeto en los constructores y / o métodos de inicialización manual como init()
Inicializa la bar
a algún valor que nunca puede ocurrir cuando llamas a la función something()
en el constructor.
Por ejemplo:
Foo(): bar(-1)
{
}
Luego verifique el valor -1
en la función get_bar
.
(hmmm Laserallan también publicó esa respuesta 1 minuto antes :-( ;-))