Using variable defined in if statement

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
class Tournament    {
    public:
        Tournament();

        int startGame(string Player);

    private:

};

Tournament::Tournament()    {
}

int Tournament::startGame(string Player)   {
    int length;
    int i=0;
    int counter=0;
    string player[8];


    for (i=0;i<length;i++)  {
        if (Player[i]=32)  {
            counter++;
        }   else    {
            player[counter] += Player[i];
        }
    }

    if (player[0]=="Avalanche") { //identify each player.
        Avalanche player1;
    }   else if (player[0]=="Bureaucrat")   {
        Bureaucrat player1;
    }   else if (player[0]=="Toolbox")  {
        Toolbox player1;
    }   else if (player[0]=="Crescendo") {
        Crescendo player1;
    }   else if (player[0]=="PaperDoll")    {
        PaperDoll player1;
    }   else if (player[0]=="FistfullODollars") {
        FistfullODollars player1;
    }

        if (player[1]=="Avalanche") {
        Avalanche player2;
    }   else if (player[1]=="Bureaucrat")   {
        Bureaucrat player2;
    }   else if (player[1]=="Toolbox")  {
        Toolbox player2;
    }   else if (player[1]=="Crescendo") {
        Crescendo player2;
    }   else if (player[1]=="PaperDoll")    {
        PaperDoll player2;
    }   else if (player[1]=="FistfullODollars") {
        FistfullODollars player2;
    }

        if (player[2]=="Avalanche") {
        Avalanche player3;
    }   else if (player[2]=="Bureaucrat")   {
        Bureaucrat player3;
    }   else if (player[2]=="Toolbox")  {
        Toolbox player3;
    }   else if (player[2]=="Crescendo") {
        Crescendo player3;
    }   else if (player[2]=="PaperDoll")    {
        PaperDoll player3;
    }   else if (player[2]=="FistfullODollars") {
        FistfullODollars player3;
    }

        if (player[3]=="Avalanche") {
        Avalanche player4;
    }   else if (player[3]=="Bureaucrat")   {
        Bureaucrat player4;
    }   else if (player[3]=="Toolbox")  {
        Toolbox player4;
    }   else if (player[3]=="Crescendo") {
        Crescendo player4;
    }   else if (player[3]=="PaperDoll")    {
        PaperDoll player4;
    }   else if (player[3]=="FistfullODollars") {
        FistfullODollars player4;
    }

        if (player[4]=="Avalanche") {
        Avalanche player5;
    }   else if (player[4]=="Bureaucrat")   {
        Bureaucrat player5;
    }   else if (player[4]=="Toolbox")  {
        Toolbox player5;
    }   else if (player[4]=="Crescendo") {
        Crescendo player5;
    }   else if (player[4]=="PaperDoll")    {
        PaperDoll player5;
    }   else if (player[4]=="FistfullODollars") {
        FistfullODollars player5;
    }

        if (player[5]=="Avalanche") {
        Avalanche player6;
    }   else if (player[5]=="Bureaucrat")   {
        Bureaucrat player6;
    }   else if (player[5]=="Toolbox")  {
        Toolbox player6;
    }   else if (player[5]=="Crescendo") {
        Crescendo player6;
    }   else if (player[5]=="PaperDoll")    {
        PaperDoll player6;
    }   else if (player[5]=="FistfullODollars") {
        FistfullODollars player6;
    }

        if (player[6]=="Avalanche") {
        Avalanche player7;
    }   else if (player[6]=="Bureaucrat")   {
        Bureaucrat player7;
    }   else if (player[6]=="Toolbox")  {
        Toolbox player7;
    }   else if (player[6]=="Crescendo") {
        Crescendo player7;
    }   else if (player[6]=="PaperDoll")    {
        PaperDoll player7;
    }   else if (player[6]=="FistfullODollars") {
        FistfullODollars player7;
    }

        if (player[7]=="Avalanche") {
        Avalanche player8;
    }   else if (player[7]=="Bureaucrat")   {
        Bureaucrat player8;
    }   else if (player[7]=="Toolbox")  {
        Toolbox player8;
    }   else if (player[7]=="Crescendo") {
        Crescendo player8;
    }   else if (player[7]=="PaperDoll")    {
        PaperDoll player8;
    }   else if (player[7]=="FistfullODollars") {
        FistfullODollars player8;
    }


    //the real tournament
    Ref a1 = Ref(player1,player2);
    Ref a2 = Ref(player3,player4);
    Ref a3 = Ref(player5,player6);
    Ref a4 = Ref(player7,player8);
}


The Error:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
||=== Build file: "no target" in "no project" (compiler: unknown) ===|
C:\Users\Asus\Desktop\Coding Works\Cdoubleplus\Year 2\prac 3\prac3.cpp||In member function 'int Tournament::startGame(std::string)':|
C:\Users\Asus\Desktop\Coding Works\Cdoubleplus\Year 2\prac 3\prac3.cpp|439|error: 'player1' was not declared in this scope|
C:\Users\Asus\Desktop\Coding Works\Cdoubleplus\Year 2\prac 3\prac3.cpp|439|error: 'player2' was not declared in this scope|
C:\Users\Asus\Desktop\Coding Works\Cdoubleplus\Year 2\prac 3\prac3.cpp|440|error: 'player3' was not declared in this scope|
C:\Users\Asus\Desktop\Coding Works\Cdoubleplus\Year 2\prac 3\prac3.cpp|440|error: 'player4' was not declared in this scope|
C:\Users\Asus\Desktop\Coding Works\Cdoubleplus\Year 2\prac 3\prac3.cpp|441|error: 'player5' was not declared in this scope|
C:\Users\Asus\Desktop\Coding Works\Cdoubleplus\Year 2\prac 3\prac3.cpp|441|error: 'player6' was not declared in this scope|
C:\Users\Asus\Desktop\Coding Works\Cdoubleplus\Year 2\prac 3\prac3.cpp|442|error: 'player7' was not declared in this scope|
C:\Users\Asus\Desktop\Coding Works\Cdoubleplus\Year 2\prac 3\prac3.cpp|442|error: 'player8' was not declared in this scope|
C:\Users\Asus\Desktop\Coding Works\Cdoubleplus\Year 2\prac 3\prac3.cpp|464|error: 'b1' was not declared in this scope|
C:\Users\Asus\Desktop\Coding Works\Cdoubleplus\Year 2\prac 3\prac3.cpp|467|error: 'b2' was not declared in this scope|
C:\Users\Asus\Desktop\Coding Works\Cdoubleplus\Year 2\prac 3\prac3.cpp|501|error: 'b2' was not declared in this scope|
C:\Users\Asus\Desktop\Coding Works\Cdoubleplus\Year 2\prac 3\prac3.cpp|537|error: 'b2' was not declared in this scope|
C:\Users\Asus\Desktop\Coding Works\Cdoubleplus\Year 2\prac 3\prac3.cpp|571|error: 'b2' was not declared in this scope|
||=== Build failed: 13 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|


I know it's a long code for such a small question but I really want you guys to see the whole picture (and it's embarrassing that this is also my practical at uni haha).

So I'm trying to build a class that not only define a list of variable as the user enter in a string. Example: if someone enter "Batman Superman", I'll have 2 variable player1 (batman class) and player2 (superman class) defined.
Afterward I'll have player1 and player2 fight off each other. But since player1 and player2 will be defined in the if statement, it won't be allowed.

Any suggestion? Thank you.
Last edited on
Line 22: = should be ==.
I hope that class batman and class superman derive from the same base class. I'll call it superhero. Player1 and player 2 should be pointers to class superhero. You create the right superhero with a factory:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
superhero *makeSuperhero(const string &kind)
{
        if (kind =="Avalanche") {
        return new Avalance;
    }   else if (kind=="Bureaucrat")   {
        return new Bureaucrat;
    }   else if (kind =="Toolbox")  {
        return new Toolbox;
    }   else if (kind =="Crescendo") {
        return new Crescendo;
    }   else if (kind =="PaperDoll")    {
        return new PaperDoll;
    }   else if (kind =="FistfullODollars") {
        return new FistfullODollars;
    }

    cerr << "Unknown kind \"" << kind << "\" in makeSuperhero\n";
    return nullptr;
}


Now startGame becomes a lot easier. Notice that I changed player1...player8 into an array. Same with ref1...ref4. Any time you find yourself writing something1, something2, something3,..., you should probably replace it with an array or vector.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
int Tournament::startGame(string Player)   {
    int length;
    int i=0;
    int counter=0;
    string playerName[8];
    superHero *player[8];


    for (i=0;i<length;i++)  {
        if (Player[i]==32)  {// dmh
            counter++;
        }   else    {
            playerName[counter] += Player[i];
        }
    }

    for (size_t i=0; i<8; ++i) {
        player[i] = makeSuperHero(playerName[i]);
    }

    //the real tournament
    Ref refs[4];
    for (size_t i=0; i<4; ++i) {
        refs[i] = Ref(player[2*i], player[2*i+1]);
    }
   // TODO: add code to delete pointers in player array
   // TODO: return something from this function, or change it to void
}

Here is a snippet of your code.

29
30
31
32
33
34
35
36
37
38
39
40
41
    if (player[0]=="Avalanche") { //identify each player.
        Avalanche player1;
    }   else if (player[0]=="Bureaucrat")   {
        Bureaucrat player1;
    }   else if (player[0]=="Toolbox")  {
        Toolbox player1;
    }   else if (player[0]=="Crescendo") {
        Crescendo player1;
    }   else if (player[0]=="PaperDoll")    {
        PaperDoll player1;
    }   else if (player[0]=="FistfullODollars") {
        FistfullODollars player1;
    }


You have defined player1 6 times, each time with a different type. And each time, as soon as player1 is defined, it goes out of scope and is destroyed. So, by the end of line 41, there is no longer a player1 variable defined.

You need to define player1 as a pointer to a base class, and in each of these if statements, create an object dynamically and assign it to the pointer.

29
30
31
32
33
34
35
36
37
38
    PlayerBaseClass* player1;
    if (player[0]=="Avalanche") { //identify each player.
        player1 = new Avalanche;
    }   else if (player[0]=="Bureaucrat")   {
        player1 = new Bureaucrat;
    }
    // etc.

    // at the end
    delete player1;


Make sure you delete the pointers when you are done (or, better yet, use a smart pointer to do it for you).

Better yet, make an array of PlayerBaseClass*, and add a new function that does the common stuff.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
    
PlayerBaseClass* populatePlayer(std::string typeString)
{
    PlayerBaseClass* player;    
    if (typeString=="Avalanche") { //identify each player.
        player = new Avalanche;
    }   else if (typeString=="Bureaucrat")   {
        player = new Bureaucrat;
    }
    // etc.

    return player;
}

// Code from startGame

    ...
    PlayerBaseClass* players[8];

    for (int i = 0; i < 8; ++i)
    {
        players[i] = populatePlayer[i];
    }


    // when done
    for (int i = 0; i < 8; ++i)
    {
        delete players[i];
        players[i] = nullptr;
    }

    ...


By the way, the code snippet you gave us uses an undefined variable length in line 21.
For the polymorphic bit, use a unique_ptr instead of a raw pointer.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <iostream>
#include <memory>
#include <string>

struct PlayerBaseClass
{
  virtual std::string name() const = 0;
  virtual ~PlayerBaseClass() 
  {
    std::cout << "destroying player\n";
  }
};

struct Bureaucrat: public PlayerBaseClass
{
  std::string name() const { return "Bureaucrat"; }
};

struct Shopkeep: public PlayerBaseClass
{
  std::string name() const { return "Shopkeep"; }
};

int main()
{
  std::unique_ptr<PlayerBaseClass> player;
  
  player = std::make_unique<Bureaucrat>();
  std::cout << player->name() << "\n";
  
  player = std::make_unique<Shopkeep>();
  std::cout << player->name() << "\n";
}
Bureaucrat
destroying player
Shopkeep
destroying player

Hope this helps.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
superhero *makeSuperhero(const string &kind)
{
        if (kind =="Avalanche") {
        return new Avalance;
    }   else if (kind=="Bureaucrat")   {
        return new Bureaucrat;
    }   else if (kind =="Toolbox")  {
        return new Toolbox;
    }   else if (kind =="Crescendo") {
        return new Crescendo;
    }   else if (kind =="PaperDoll")    {
        return new PaperDoll;
    }   else if (kind =="FistfullODollars") {
        return new FistfullODollars;
    }

    cerr << "Unknown kind \"" << kind << "\" in makeSuperhero\n";
    return nullptr;


Hi guys, thanks for the great reply.
In dhayden's function, he used const string as the input type. Can anyone explain why do I have to use const, instead of just string?
why do I have to use const, instead of just string?

You don't have to, but its more efficient. If you use a string then the program has to make a copy of the string. Using a const string & means that it can pass a reference, which is very easy. Making it a const reference means that you promise not to modify the string and the compiler will complain if you try to. That's not strictly necessary but it's good practice since the caller probably expects that you won't change their string.
Topic archived. No new replies allowed.