2011-01-06 28 views
7

Tengo alguna pregunta sobre la evaluación diferida de C++, ¿puedo estar seguro de que este fragmento del código siempre funcionará, o es una mala idea? ¿si es así por qué? Gracias de antemanobuenas prácticas en C++ (evaluación diferida)

si (currentNode == 0 || * currentNode == elemento) { retorno; }

+0

Siempre funcionará, pero podría ser una mala idea. :) Se necesita más contexto para evaluar el código. –

+0

@Karl: ¿qué crees que es malo al respecto? –

+0

** Puede ** estar mal, * según el contexto *, que 'currentNode' es un puntero en primer lugar, o que está permitido que sea nulo, o que la lógica funcione de esta manera, o ... –

Respuesta

19

Se garantiza al trabajo: se evalúan cadenas lógicas AND y OR expresión de izquierda a derecha, y si la primera subexpresión satisface la condición, no se evalúan más subexpresiones.

En su caso, si currentNode es nulo, nunca será desreferenciado por la segunda subexpresión, por lo que el código es seguro.

Como @jdv señaló, sin embargo, esto se llama evaluación de cortocircuito, no evaluación perezosa. Esta última es una técnica de programación en la que usted, de forma transparente para el cliente, calcula un valor requerido solo la primera vez cuando se necesita concretamente. Un simple ejemplo:

class Example { 
    SomeClass *theObject = null; 
public: 
    SomeClass *getTheObject() { 
    if (!theObject) { 
     theObject = doResourceConsumingCalculation(); 
    } 
    return theObject; 
    } 
}; 

Tenga en cuenta que el cliente de Example no es consciente de los detalles de implementación que theObject se evalúa con pereza, por lo que son libres de cambiar de ida y vuelta entre la evaluación ansiosos y perezoso sin afectar la interfaz pública de la clase.

(Por supuesto, en el código de producción de bienes, getTheObject deben implementarse en un archivo separado CPP, y probablemente debería incluir la sincronización, el código de control de errores, etc Esto es sólo un ejemplo simplista :-)

+0

expresión sub * h * – marcog

+0

@marcog, gracias, fijo :-) –

11

Sí, esto es seguro. Se llama evaluación booleana de cortocircuito.

Para completenes que merece mencionar que, en principio, es posible anular el || y & & operadores. Si lo hace, se romperá la evaluación de cortocircuito y, por lo tanto, no se recomienda.

+0

1 para aclarar la terminología :-) –

3

Para perezoso -evaluación en un entorno de subprocesos múltiples, debería considerar usar boost :: una vez para realizar la carga única.

class Example 
{ 
    mutable boost::once_flag flag; 
    mutable SomeClass * theObject; 

    void loadTheObject() const; 

public: 
    Example() : 
     flag(BOOST_ONCE_INIT), 
     theObject(NULL) 
    { 
    } 

    SomeClass * getTheObject() const 
    { 
     boost::call_once(flag, boost::bind(&Example::loadTheObject, this)); 
     return theObject; 
    } 
}; 
+0

Nota: ahora hay una construcción "una vez" en C++ estándar. Si existe la posibilidad de que el valor no se cargue, es mejor que el método que carga no "gotee" una excepción. Por lo tanto, es una buena idea tener algún tipo de decorador en su caché que muestre el estado fallido. – CashCow