2009-11-24 10 views
5

Estoy tratando de declarar una variable en un bloque if-else de la siguiente manera:Declarar una variable en un bloque if-else en C++

int main(int argc, char *argv[]) { 

    if (argv[3] == string("simple")) { 
     Player & player = *get_Simple(); 
    } else if (argv[3] == string("counting")) { 
     Player & player = *get_Counting(); 
    } else if (argv[3] == string("competitor")) { 
     Player & player = *get_Competitor(); 
    } 

    // More code 
} 

Pero, estoy consiguiendo los siguientes errores cuando intento compilar:

driver.cpp:38: error: unused variable ‘player’
driver.cpp:40: error: unused variable ‘player’
driver.cpp:42: error: unused variable ‘player’
driver.cpp:45: error: ‘player’ was not declared in this scope

¿Alguna idea?

Respuesta

20

Su problema es que el reproductor queda fuera de alcance en cada bloque if/else if.

Debe declarar su variable por encima de todas las declaraciones if.

Pero no puede usar una referencia para eso porque debe inicializar una referencia de inmediato.

En cambio es probable que quieren algo como esto:

int main(int argc, char *argv[]) { 

    Player * pPlayer = NULL; 
    if (argv[3] == string("simple")) { 
     pPlayer = get_Simple(); 
    } else if (argv[3] == string("counting")) { 
     pPlayer = get_Counting(); 
    } else if (argv[3] == string("competitor")) { 
     pPlayer = get_Competitor(); 
    } 

    //Then if you really want to... 
    Player &player = *pPlayer; 

} 
+3

Este consejo es correcto, pero le sugiero que podría evitar todo el puntero/conmutador de referencia al final al tener un método de fábrica que tome su parámetro de tipo y devuelve un 'Player *'. Entonces su método principal se convierte en 'Player & player = * getPlayerByType (argv [3]);', y las declaraciones 'if' en' getPlayerByType() 'cada devolución directamente, evitando así toda esa fealdad de variable local. – bradheintz

+2

@bradheintz: Ese consejo no ayuda en lo más mínimo (de hecho, complica la respuesta al proporcionar consejos espurios). Es obvio que el OP realmente está tratando de hacer exactamente lo que usted dice (y devolver una referencia (en lugar de un puntero como en su solución)). Pero ha publicado la versión simplista compilable de la pregunta aquí. Si desea publicar una respuesta, haga eso, al menos podemos darle una calificación negativa por no responder la pregunta. –

+0

No estoy seguro de lo espúreo de empaquetar la creación de objetos en una función de responsabilidad única, eliminando una variable local innecesaria y haciendo que la función main() sea más escaneable, pero si te hace más feliz llamar a mi consejo "espurio", o para llamar a un refinamiento sugerido de los buenos consejos de Brian R. Bondy "abarrotar" sin apoyar la afirmación, ve por ello. – bradheintz

3

Si coloca una variable estática dentro de un ámbito, delimitado por { }, esa variable ya no estará disponible cuando finalice el alcance.

Tal vez puedas probar:

int main(int argc, char *argv[]) { 

    // TODO: validate argc and argv here 
    if (argc < 3) { 
     printf("error: not enough arguments\n"); 
     exit(1); 
    } 

    Player* player_ptr = NULL; 
    if (argv[3] == string("simple")) { 
     player_ptr = get_Simple(); 
    } else if (argv[3] == string("counting")) { 
     player_ptr = get_Counting(); 
    } else if (argv[3] == string("competitor")) { 
     player_ptr = get_Competitor(); 
    } 

    if (!player_ptr) { 
     printf("error: invalid argument %s\n", argv[3]); 
     exit(1); 
    } 

    Player& player = *player_ptr; 

    // More code 
} 
+1

Una referencia debe tener un valor inicial. –

+0

¿Compilará esto? las referencias se deben inicializar ... – stefanB

+0

Sí, lo eché a perder. Traté de arreglarlo. – Parappa

0

En

if (argv[3] == string("simple")) { 
    Player & player = *get_Simple(); 
} 

La variable sólo existe entre los {} 's. Cuando llegue al }, la variable no se ha utilizado y se descartará, y nunca se habrá utilizado.

2

Usted ha declarado tres player variables separadas en tres ámbitos diferentes, y el mensaje de error está diciendo exactamente lo que significa.

Debe declarar una variable de un solo jugador fuera de la if -statement y asignar el resultado. Esto es complicado, ya que el jugador es una referencia; debes inicializarlo una vez.

Puede poner el if -statement en una función (digamos GetPlayer()) que devuelve un puntero al objeto, y luego inicializar el reproductor con * GetPlayer().

16

Otros han sugerido punteros. Sin embargo, el operador condicional también se puede usar.

Player & player = argv[3] == string("simple") ? get_Simple() 
       : argv[3] == string("counting") ? get_Counting() 
       : get_Competitor(); 
0
#include <map> 

int main(int argc, char **argv) 
{ 
    typedef std::map<std::string, Player*(*)()> lookup; 
    lookup mapping; 

    mapping["simple"] = get_Simple; 
    mapping["counting"] = get_Counting; 
    mapping["competitor"] = get_Competitor; 

    lookup::const_iterator it = mapping.find(argv[3]); 
    if (it == mapping.end()) 
    { 
     std::cout << "illegal argument\n"; 
    } 
    else 
    { 
     Player& player = *it->second(); 
     // more code 
    } 
} 
Cuestiones relacionadas