2009-11-24 9 views
5

Ich versuche, eine Variable in einem if-else-Block zu erklären, wie folgt:Deklarieren eine Variable in einem if-else-Block in 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 
} 

Aber ich bin immer die folgenden Fehler, wenn ich versuche zu kompilieren:

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

Irgendwelche Ideen?

Antwort

20

Ihr Problem ist, dass Spieler in jedem if/else if-Block außerhalb des Geltungsbereichs fällt.

Sie müssen Ihre Variable über alle if-Anweisungen deklarieren.

Sie können jedoch keine Referenz verwenden, da Sie eine Referenz sofort initialisieren müssen.

Stattdessen möchten Sie wahrscheinlich so etwas wie dieses:

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

Dieser Ratschlag ist Ton, aber ich würde vorschlagen, dass Sie den ganzen Zeiger/die Reference switcheroo am Ende vermeiden konnten, indem Sie eine Fabrikmethode haben, die Ihren Typparameter nimmt und gibt einen 'Player *' zurück. Also wird Ihre Hauptmethode zu 'Player & player = * getPlayerByType (argv [3]);', und die 'if'-Anweisungen in' getPlayerByType() 'kommen jeweils direkt zurück und vermeiden so alle lokalen variablen Hässlichkeiten. – bradheintz

+2

@bradheintz: Dieser Rat hilft nicht im Geringsten (in der Tat verstopft es die Antwort mit falschen Ratschlägen). Es ist offensichtlich, dass das OP tatsächlich versucht, genau das zu tun, was Sie sagen (und eine Referenz (anstatt einen Zeiger wie in Ihrer Lösung) zurückzugeben). Aber hat die simpel kompilierbare Version der Frage hier gepostet. Wenn Sie eine Antwort schreiben möchten, dann können wir Ihnen zumindest eine negative Note geben, wenn Sie die Frage nicht beantworten. –

+0

Ich bin mir nicht sicher, was falsch daran ist, die Objekt-Erstellung in eine Single-Responsibility-Funktion zu packen, eine unnötige lokale Variable zu eliminieren und die main() -Funktion besser scanbar zu machen - aber wenn es dich glücklicher macht, meinen Rat "falsch" zu nennen, oder um eine vorgeschlagene Verfeinerung von Brian R. Bondys guten Ratschlag "überladen" zu nennen, ohne die Behauptung zu unterstützen, gehen Sie darauf ein. – bradheintz

3

Wenn Sie eine statische Variable in einen Bereich einfügen, der durch { } begrenzt ist, ist diese Variable beim Abschluss des Bereichs nicht mehr verfügbar.

Versuchen Sie stattdessen:

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

Eine Referenz muss einen Anfangswert aufweisen. –

+0

Wird das kompilieren? Referenzen müssen initialisiert werden ... – stefanB

+0

Yup, ich vermasselt. Versucht es zu reparieren. – Parappa

0

In

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

Die Variable existiert nur zwischen den {} ist. Wenn Sie die } erreichen, wurde die Variable nicht verwendet und wird verworfen, nie benutzt worden.

2

Sie drei separate player Variablen in drei verschiedenen Bereichen deklariert haben, und die Fehlermeldung sagt genau das, was es bedeutet.

Sie müssen eine Einzelspielervariable außerhalb der if -Statementangabe deklarieren und das Ergebnis zuweisen. Das ist schwierig, da der Player eine Referenz ist - Sie müssen ihn einmal initialisieren.

Sie können die if -Statement in eine Funktion (sagen GetPlayer()), die einen Zeiger auf das Objekt zurückgibt, und dann Player mit * GetPlayer() initialisieren.

16

Andere haben Hinweise vorgeschlagen. Der Bedingungsoperator kann jedoch ebenfalls verwendet werden.

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 
    } 
} 
Verwandte Themen