Jump to content
  • Advertisement
Sign in to follow this  
Lord_Spatulator

iterating through instances of a class

This topic is 4911 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

What's the easiest way? This is just a test kinda code, but im gonna have like, multiple enemies n stuff, but u know, gotta start w/ the basics. Anyways, I'm thinking im going to create the instances into an array or something? I'm kinda at a loss. Any help would be appreciated, thanks!
#include <iostream>
#include <string>

using namespace std;

//class
class Person
{
  public:
    static int nTotal;
    int ID;
    int age;
    string name;
    
    Person(int age = 0, string name = "unnamed"):
           age(age),
           name(name)
    {
      ID = nTotal;
      nTotal++;
      cout << name
           << " has been added! ("
           << ID
           << ")\n";
    }
};
int Person::nTotal = 0;

//fn declerations
void changeName(Person *pPerson);
void quit();

int main()
{
  Person dean(17, "Dean Rather"),
         reuben(18, "Reuben Baker"),
         jess(2, "Jess Grigg");
  

      
  for (int i = 0; i < Person::nTotal; i++)
      cout << "Person with ID "
           << i
           << "'s name is \n";
         //<< what do I do??? 
         

  changeName(&dean);
  
  cout << "Person "
       << dean.ID
       << "'s name is "
       << dean.name
       << "\n\n";
  quit();
  return 0;
}

void quit()
{
  char quit;
  cout << "\n\nQuitting, ok? (y)";
  cin >> quit;    
}

void changeName(Person* pPerson)
{
     pPerson->name = "Functioned!!";
}

Share this post


Link to post
Share on other sites
Advertisement
Or better yet, use an std::vector :

#include <iostream>
#include <string>
#include <vector>
using namespace std;

class Person
{
private:
string m_name;
public:
// ... ///
Person(string name) : m_name(name)
{ }
void Name(string name){ m_name = name; }
string Name(){ return m_name; }
};


int main()
{
// Make the people vector
vector<Person*> People;

// Add people into People.....
People.push_back(new Person("Fred"));
People.push_back(new Person("Joey"));
People.push_back(new Person("George"));
People.push_back(new Person("Franky"));
People.push_back(new Person("Foo"));
People.push_back(new Person("Bar"));

// Iterate through
for(vector<Person*>::iterator pos = People.begin(); pos != People.end(); pos++){
cout << (*pos)->Name() << endl;
}

cin.get();

// Destroy People... MUAHAHA
while(!People.empty()){
delete People.back(); // delete the person at the back
People.pop_back();
}
People.clear(); // Clear it just to make sure (not required)

}

Share this post


Link to post
Share on other sites
If we're going to use the Standard C++ Library, let's use the Standard C++ Library.

Building on Rob Loach's example, we provide a few modifications:

void DeletePerson(Person * p)
{
if(p)
{
delete p;
p = 0;
}
}

//...

#include <algorithm>

int main()
{
// everything as before...

// Destroy People... MUAHAHA
std::for_each(People.begin(), People.end(), DeletePerson);
People.empty();

return 0;
}



Why the change? First, it makes the client code more comprehensible. If you name your predicate carefully, it becomes transparent what is transpiring (ooh, alliteration!) Second, it reduces the amount of code duplication, because there's always a possibility that you'll allocate more Persons somewhere else. If you template your predicate, you can even use the same object everywhere for similar types of allocation.

Happy hacking.

...as he rides off into the sunset.

Share this post


Link to post
Share on other sites
Hey, cool, thanks guys!

So what if I waned to make people on the fly, like, have a fn that generates a new person, "person1", "person2" or whatever, so I can have lots of them, and I don't need to individually write one line for each instance?

like, I might want

for (int i = 0; i < 10; i ++)
createPerson(i);


or something...
?

Share this post


Link to post
Share on other sites
I have a different way of organizing the array of people. Using the std::map data type you can look up a person's information based on their name, however if you have duplicate names it won't work realiably (it should return the first name found).


#include <iostream>
#include <string>
#include <map>

using namespace std;

class person
{
public:
string m_name;
int m_age;

person(string M_NAME, int M_AGE)
: m_name(M_NAME), m_age(M_AGE)
{
}
person()
: m_name("John Doe"), m_age(20)
{
}

void report()
{
cout << endl;
cout << "My name is: " << m_name << endl;
cout << "My age is: " << m_age << endl;
}

};


int main()
{
map<string, person> personList;

person tmp = person("Bob Villa", 50);
personList[tmp.m_name] = tmp;
tmp = person("George Carlin", 60);
personList[tmp.m_name] = tmp;
tmp = person("Punky Brewster", 35);
personList[tmp.m_name] = tmp;

char msg[50];
string str;

for(int i=1;i<5;++i)
{
sprintf(msg, "person%d", i);
str=msg;
tmp = person(str, 18);
personList[tmp.m_name] = tmp;
}

map<string, person>::iterator it = personList.begin();
map<string, person>::iterator end = personList.end();

for(;it!=end;++it)
{
cout << it->first;
personList[it->first].report();
}
return 0;
}



This also does a loop that adds a person to the list whose pretty generic, though any of the other examples could do the same just as easily. Hope this helps!

Share this post


Link to post
Share on other sites
Quote:
Original post by Lord_Spatulator
So what if I waned to make people on the fly, like, have a fn that generates a new person, "person1", "person2" or whatever, so I can have lots of them, and I don't need to individually write one line for each instance?
Dynamic object creation:

//...

std::list<Person *> people;
for(int i = 0; i < SomeLargishNumber; ++i)
people.push_back(new Person);

//...

std::for_each(people.begin(), people.end(), DeletePerson);

//...


This highlights the benefit of having written a predicate and of using the Standard C++ Library containers: changing the type and allocation of data in the container didn't affect any of the rest of the code!

Share this post


Link to post
Share on other sites
Quote:
Original post by Oluseyi
If we're going to use the Standard C++ Library, let's use the Standard C++ Library.

Building on Rob Loach's example, we provide a few modifications:
*** Source Snippet Removed ***

Why the change? First, it makes the client code more comprehensible. If you name your predicate carefully, it becomes transparent what is transpiring (ooh, alliteration!) Second, it reduces the amount of code duplication, because there's always a possibility that you'll allocate more Persons somewhere else. If you template your predicate, you can even use the same object everywhere for similar types of allocation.

Happy hacking.

...as he rides off into the sunset.

Watchout, people.empty() does not "empty" the vector. The empty member function of containers just checks to see if the container is empty (returning a bool). To clear a vector either use people.clear() or people.resize( 0 )

Share this post


Link to post
Share on other sites
ok, cool, I think I've got most of this understood about now, (now I know im probebly not iterating through my array right, but I think the vector's right.)
My question is, am I using the pointers correctly, or am I actually passing the entire vector through to the fn each time?

also, if you un/comment the final call to printDetails, you'll see it's quite errorous to call data from the instances, probebly because it's empty or something, but does anyone have any sugegstions about that?

Thanks.


//deans programmy thing
//goal: to access data members of a class
//public data members via pointers
//from a function outside of main.

#include <iostream>
#include <string>
#include <vector>

using namespace std;

//class
class Person
{
private:
string m_name;
static int m_Total;
int m_ID;
int m_age;

public:
Person(string name = "John Doe",
int age = 20):
m_name(name),
m_age(age)
{
m_ID = m_Total;
m_Total++;
cout << m_name
<< " has been added! ("
<< m_ID
<< ")\n";
}
void setName(string name)
{ m_name = name; }

string getName()
{ return m_name; }

int getID()
{ return m_ID; }
};
int Person::m_Total = 0;

//fn declerations
void changeName(Person *pPerson);
void quit();
void printDetails(vector<Person*> People);
void clearList(vector<Person*> vector);

int main()
{
//explain we are about to create people
cout << "Adding people.\n";

//Make Array of Names
string names[] = {"Dean",
"Jason",
"Fred",
"Nick",
"Simon",
"Matt",
"Luke",
"END"};

//make a vector names people that holds persons
vector<Person*> People;

//add people to vector
for (int i = 0; names != "END"; i++)
People.push_back(new Person(names));

cout << "\n\nHeres severyone's details!\n";
printDetails(People);

cout << "\nKilling everybody:\n";
clearList(People);

cout << "\n\nHeres severyone's details again!\n";
//printDetails(People);

quit();
return 0;
}

void printDetails(vector<Person*> People)
{
for (vector<Person*>::iterator pos = People.begin();
pos != People.end();
pos++)
{
cout << "Name: "
<< (*pos)->getName()
<< ",\tID: "
<< (*pos)->getID()
<< "\n";
}

}


void clearList(vector<Person*> vector)
{
while(!vector.empty())
{
cout << "Killing "
<< vector.back()->getName()
<< endl;
delete vector.back();
vector.pop_back();
}
}

void quit()
{
char quit;
cout << "\n\nQuitting, ok? (y)";
cin >> quit;
}

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!