En este escenario, la bomba de gas de un tiempo extra después de los usuario pulse '0'. Suponiendo que esto no sea deseado, tiene lo que se conoce como un "error de uno por uno". Puedes solucionar este problema (y eliminar la variable temporal) de reordenación de su función como sigue:
void GasPump::dispense()
{
while (true) {
cout << "Press any key, or enter to dispense.\n"
<< "Or press 0 to stop: \n";
if (cin.get() == '0')
break;
gasDispensed = gasDispensed + gasDispensedPerCycle;
charges = costPerGallon*gasDispensed;
displayGasNCharges();
}
}
evitar el uso de una sentencia break, puede utilizar la siguiente construcción:
bool GasPump::shouldDispenseGas()
{
cout << "Press any key, or enter to dispense.\n"
<< "Or press 0 to stop: \n";
return (cin.get() != '0');
}
void GasPump::dispense()
{
while (shouldDispenseGas()) {
gasDispensed = gasDispensed + gasDispensedPerCycle;
charges = costPerGallon*gasDispensed;
displayGasNCharges();
}
}
EDITAR (2011 Septiembre 27): @TonyK El mero hecho de que un idioma proporcione una función no significa que deba usarse. La declaración goto
es un ejemplo clásico de esto.
De acuerdo, con un bucle tan simple, realmente no hay diferencia entre usar una función y la ruptura. Ambos son claros. Sin embargo, cuando se agregan funciones adicionales un mes (o años) más tarde, junto con condiciones adicionales para salir del ciclo, es muy fácil encontrar declaraciones if
con lógica compleja dentro de un bucle que es tan grande, tiene una dificultad el tiempo encuentra su comienzo, y mucho menos los puntos de salida. Una de las maneras de luchar contra este tipo de código inflado es escribir funciones cortas, simples y enfocadas que tienen un buen nombre. Si haces esto, el código se documenta solo. Compare
while (true)
frente
while (shouldDispenseGas())
Del mismo modo, comparar esto con el STL for_each
algoritmo. Claro, std::for_each(v.begin(), v.end(), &foo);
es un poco más corto que for (int i = 0; i < v.size(); ++i) { ...body of foo()... }
. Pero la verdadera ventaja es que es más fácil ver cuál es la intención. En el for_each
inmediatamente verá que hará algo una vez, y solo una vez, a cada elemento. En el ciclo for, no tienes idea. El contador de bucle i
puede cambiarse en el bucle. Un break
también puede estar oculto dentro. Al eludir esta declaración break
e insertar la lógica en shouldDispenseGas
, inmediatamente comprende las condiciones bajo las cuales el ciclo continuará y finalizará.
Ooh! No me di cuenta cuando usaba un número decimal como un char, tenía que poner las comillas a su alrededor, es bueno saberlo, ¡muchas gracias, amigo! –
@ blakejc70 Dado que stop es un char y con la sobrecarga del método C++, su llamada a cin.get se enruta a través de una lógica de manejo de entrada que devolverá un código de carácter. Así que pare == '0' == 48 (asumiendo el conjunto de caracteres ASCII). – David