0

How can one iterate through an array to manipulate or access different objects and their member functions? I have 10 objects. Right now I have the same code accessing each object member function and manipulating object data basically copied and pasted for each object. I'm just wondering if there is a way to use a loop to write that code one time and have it loop through all 10 objects.

Instead of doing so manually like below:

Color red.set();
Color green.set();
Color blue.set();
Color yellow.set();
Color purple.set();
      ...

Is there a way to do this with a loop, such as the following:

colors[5] = {"red", "green", "blue", "yellow", "purple", ...};

for(int i = 0; i < 10; i++){
    Color colors[i].set();
}

I know that for PHP to do something similar would be this:

$colors = array("red", "green", "blue", "yellow", "purple" ...);

for($i = 0; $i < 10; $i++){
    ${$colors[$i]} = $colors[$i];
    // $red = "red";
}

Is it possible to do this for C++?

Below is another example as to why I am asking this and what I'm getting at: Instead of:

if(grid[row][col].ship == "red")
{
    red.setShipDamage();

    if(red.getShipSunk() == true)
        red.destroy();
}
else if(grid[row][col].ship == "green")
{
    green.setShipDamage();

    if(green.getShipSunk() == true)
        green.destroy();
}
else if( ... )

To do all of this once in a loop:

for(int i = 0; i < 10; i++)
{
    if(grid[row][col].ship == colors[i])
    {
        **colors[i]**.setShipDamage();

        if(**colors[i]**.getShipSunk() == true)
            **colors[i]**.destroy();
    }
}
reformed
  • 4,505
  • 11
  • 62
  • 88
  • 1
    Yes, as an example of how it is done in a different language – reformed Sep 06 '12 at 20:33
  • Your're better off trying to explain what you are actually trying to do in C++. Not everyone is lucky enough to know PHP. – juanchopanza Sep 06 '12 at 20:34
  • 1
    What do you mean by `Color red.set();`? Should it be function call or variable definition? It's not a c++ statement. – Mikhail Sep 06 '12 at 20:34
  • set() could be a void function that sets, for example, various variables – reformed Sep 06 '12 at 20:35
  • While I don't know any PHP, I find the example code clarifying. Thanks! :) – Magnus Hoff Sep 06 '12 at 20:36
  • @eq-, the set() was an example. I'm wondering how to iterate through an array of names to instantiate objects or access object member functions. The PHP script is an example, and I'd use ${$color} so that I could use a loop to execute the same code written once rather than doing so manually by using multiple $red, $blue, $green, etc. – reformed Sep 06 '12 at 20:39
  • Updated question with example code – reformed Sep 06 '12 at 20:49
  • PHP variables are kind of keys in a global associative container; that's why you can add and remove them at will, based on user input and what-not. They are rather different from C++ variables that are (oversimplification ->) often little more than names for offsets from the stack pointer. – eq- Sep 06 '12 at 20:49
  • 3
    Why are you storing strings in your grid, instead of pointers to your ships? (If you want a connection between a string and a ship, you need an associative container from strings to ships which describes these connections.) – eq- Sep 06 '12 at 20:50
  • I have 10 objects. Right now I have the same code accessing each object member function and manipulating object data basically copied and pasted for each object. I'm just wondering if there is a way to use a loop to write that code one time and have it loop through all 10 objects. – reformed Sep 06 '12 at 20:55

4 Answers4

3

You need to do something like this:

std::map<std::string, Color*> colors;
colors["red"] = &red;
colors["green"] = &green;
colors["blue"] = &blue;
colors["purple"] = &purple;

///....
Color *color = colors[grid[row][col].ship];
color->setShipDamage();
if(color->getShipSunk() == true)
    color->destroy();

I hope it helps.

Sergiowero
  • 31
  • 2
2

Your question is somewhat confusing. You need to provide what the Color class does. Is this what you want?

Color colors[5];
char *color_txt[5] = {"red", "green", "blue", "yellow", "purple"};

for (int i = 0; i < 5; i++){
    colors[i].set(color_txt[i]);
}

Based on your edited question, you can create an array of objects as I described:

Color colors[10];

Assuming each object has a default constructor. Then you can access each object through an index in the array. So your example works as expected:

for(int i = 0; i < 10; i++)
{
    if(grid[row][col].ship == colors[i])
    {
        colors[i].setShipDamage();

        if(colors[i].getShipSunk() == true)
            colors[i].destroy();
    }
}

Also, your Color class should have on overriden equality operator.

001
  • 13,291
  • 5
  • 35
  • 66
1

It's not entirely clear what it is you want to do, but here's a stab at it:

Color red, green, blue, yellow, purple;
Color *colors[5] = {&red, &green, &blue, &yellow, &purple};
for (int i = 0; i < 5; i++) {
   colors[i]->set();
}
Keith Randall
  • 22,985
  • 2
  • 35
  • 54
1

Your example is convoluted and poorly designed to begin with. If the grid simply stored references (well, actually pointers) to the ships, you wouldn't need to loop to begin with! Consider:

if (Ship* ship = grid[y][x].ship()) {// ship() returns nullptr if there's no ship
    ship->setDamage();
    if (ship->sunk())
        // ...
}

If on the other hand you would like to associate strings with ships, you need an associative container, like unordered_map from the Standard Library:

Ship red, green, blue, white;
std::unordered_map<std::string, Ship*> = { { "red", &red },
                                           { "green", &green },
                                           /* ... */ };
eq-
  • 9,986
  • 36
  • 38