I'm making a program where there is a function that asks how many players there are, and depending on the answer, it makes an array of classes that size. How can I access the array of classes from other functions? I thought I would just make it global, but how can I do that with it still being dependant on the answer the user gives? Here's my code: (If you run it, it will give you the error I need help solving)

/* ISU program created by Matt
   in grade 12 programming. */
#include <iostream>
#include <list>
#include <iterator>
#include <vector>
using namespace std;
class humanPlayer
     {
     public:                                                             
          humanPlayer(string thePlayersName, unsigned int thePlayersTurnNum); 
          ~humanPlayer(){};  
 
          void addToList(unsigned int countryToAdd) {countriesOwned.push_back(countryToAdd);} 
          void showList();
          void removeFromList(unsigned int countryToRemove) {countriesOwned.remove(countryToRemove);}
          void checkIfInList(unsigned int countryToCheck);
 
          string getPlayerName() {return playerName;}  
          int getPlayerTurnNum() {return playerTurnNum;}
          void setPlayerTurnNum(unsigned int newPlayerTurnNum);
 
     private:
          list<int> countriesOwned;
          string playerName;
          unsigned int playerTurnNum;
     };
     humanPlayer::humanPlayer(string thePlayersName, unsigned int thePlayersTurnNum)
          {
          playerName = thePlayersName;
          playerTurnNum = thePlayersTurnNum;
          }
 
     void humanPlayer::checkIfInList(unsigned int countryToCheck)
          {
          if(find(countriesOwned.begin(), countriesOwned.end(), countryToCheck) != countriesOwned.end())
               {
               cout << countryToCheck << " is in the list.\n";
               }
          else
               {
               cout << countryToCheck << " is NOT in the list.\n";
               }
          }
 
     void humanPlayer::showList()
          {
          copy(countriesOwned.begin(),countriesOwned.end(),ostream_iterator<int>(cout,", "));
          cout << endl;
          } 
 
     void humanPlayer::setPlayerTurnNum(unsigned int newPlayerTurnNum)
          {
          playerTurnNum = newPlayerTurnNum;
          }
 
void getName();
unsigned int numOfPlayers;
int main()
     {
     getName();
 
 
     char nameTest;
 
     for(unsigned int i=0 ; i<numOfPlayers ; i++)
          {
          nameTest = jailHouse[i].getPlayerName();
          cout << nameTest << "\n";
          }
 
 
     system("PAUSE");
     }  
 
void getName()
     {
     vector<string> playerNames;
 
     cout << "How many players will there be? ";
     cin >> numOfPlayers;
     cout << endl;
 
     humanPlayer *jailHouse[numOfPlayers];
 
     for(unsigned int i=0 ; i<numOfPlayers ; i++)
          {
          char name[256];
          cin.ignore(255,'\n');
          cout << "What is player " << (i+1) << "'s name? ";
          cin.get(name,256);
 
          jailHouse[i] = new humanPlayer(name, (i+1));
          }     
 
     }

Thanks,
-Matt

Dani AI

Generated

Two quick fixes will get this working and make it maintainable.

First, the player storage in your getName() is local, so main() (and other functions) can't see jailHouse. Also the code assigns getPlayerName() to a char variable — that will fail because the getter returns a std::string. Declaring an array with a runtime size is a variable-length array (VLA), which is not standard C++; that pattern is what causes portability/compile errors. See the C++ array rules for details: Arrays (C++ language).

A simple, idiomatic fix is to use std::vector and either return it from the function or pass it by reference. Returning a filled std::vector<humanPlayer> keeps ownership clear and avoids globals; compilers will elide/move the return efficiently. Example pattern:

std::vector<humanPlayer> makePlayers(unsigned n) {
    std::vector<humanPlayer> players;
    players.reserve(n);
    for (unsigned i = 0; i < n; ++i) {
        std::string name;
        std::getline(std::cin, name);
        players.emplace_back(name, i + 1);
    }
    return players;
}

// in main:
auto players = makePlayers(num);
for (const auto& p : players) std::cout << p.getPlayerName() << '\n';

If you need polymorphism or dynamic lifetime, store smart pointers: std::vector<std::unique_ptr<humanPlayer>> (preferred over raw new/delete). See std::vector and std::unique_ptr docs: vector | unique_ptr.

This follows 's vector suggestion but adds specifics: either return the vector or pass vector&/const vector& to other functions, avoid globals like numOfPlayers (use players.size()), and prefer smart containers to manual new/raw arrays.

>How can I access the array of classes from other functions?
Well, if you want global but not global, a Singleton with the array as a member would be plausible. Or you could pass the array around, or you could create a wrapper for the array and pass it around.

>how can I do that with it still being dependant on the answer the user gives?
If it's a vector rather than an array, I don't see the problem. The vector grows dynamically and knows its size, so all you have to do is pass around the object. If it's an array, you need to pass the pointer as well as the size, or wrap both inside of an object similar to the vector class.

I'm not sure I see the problem here.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.