массивы — Итерирование имен объектов в переполнении стека

Как можно перебирать массив для манипулирования или доступа к различным объектам и их функциям-членам? У меня есть 10 предметов. Прямо сейчас у меня есть один и тот же код, который обращается к каждой функции-члену объекта и манипулирует данными объекта, которые в основном копируются и вставляются для каждого объекта. Мне просто интересно, есть ли способ использовать цикл, чтобы написать этот код один раз и сделать так, чтобы он перебрал все 10 объектов.

Вместо того, чтобы делать это вручную, как показано ниже:

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

Есть ли способ сделать это с помощью цикла, например:

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

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

Я знаю, что для PHP сделать что-то подобное было бы так:

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

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

Возможно ли сделать это для C ++?

Ниже приведен еще один пример того, почему я спрашиваю об этом и к чему я обращаюсь: вместо:

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( ... )

Чтобы сделать все это один раз в цикле:

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();
}
}

0

Решение

Ваш вопрос несколько сбивает с толку. Вам необходимо указать, что делает класс Color. Это то, что вы хотите?

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]);
}

Основываясь на отредактированном вопросе, вы можете создать массив объектов, как я описал:

Color colors[10];

Предполагая, что каждый объект имеет конструктор по умолчанию. Затем вы можете получить доступ к каждому объекту через индекс в массиве. Итак, ваш пример работает как положено:

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();
}
}

Кроме того, ваш класс Color должен иметь переопределенный оператор равенства.

2

Другие решения

Вам нужно сделать что-то вроде этого:

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();

Я надеюсь, что это помогает.

2

Не совсем понятно, что вы хотите сделать, но вот удар:

Color red, green, blue, yellow, purple;
Color *colors[5] = {&red, &green, &blue, &yellow, &purple};
for (int i = 0; i < 5; i++) {
colors[i]->set();
}
1

Ваш пример запутан и плохо спроектирован с самого начала. Если сетка просто хранит ссылки (ну, фактически, указатели) на корабли, вам не нужно было бы зацикливаться для начала! Рассматривать:

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

Если с другой стороны, вы было бы чтобы связать строки с кораблями, вам нужен ассоциативный контейнер, например unordered_map из стандартной библиотеки:

Ship red, green, blue, white;
std::unordered_map<std::string, Ship*> = { { "red", &red },
{ "green", &green },
/* ... */ };
1
По вопросам рекламы [email protected]