Необходимо создать массив уже созданных объектов

#c #oop #pointers #reference

#c #ооп #указатели #ссылка

Вопрос:

Я создаю несколько элементов, и мне нужно настроить их как взаимодействующие друг с другом.

 Item i1 = Item("Item 1");
Item i2 = Item("Item 2");
Item i3 = Item("Item 3");
Item i4 = Item("Item 4");

i1.setInteractable({i2,i3});
i2.setInteractable({i1,i4});
i3.setInteractable({i1});
  

Это заголовок метода для метода setInteractable в Item.

 void setInteractable(Item i[]);
  

Взаимодействующие элементы хранятся как таковые:

 static Item interactableItems[25];
  

Это не работает, ошибка возникает после первой фигурной скобки. Каков правильный способ сделать это на C ?

Ответ №1:

Вы хотите хранить в своем массиве не объекты (в противном случае они будут скопированы), а ссылки на объекты.

Измените ваше хранилище и интерфейс таким образом:

 void setInteractable(Itemamp; i[]);
static Itemamp; interactableItems[25];
  

Я советую поискать в Google для:

  • скопировать конструктор
  • указатель против объекта против ссылки

Ответ №2:

C не создает динамические списки так легко, как вы пытаетесь.

Для создания динамических списков вам нужно сначала объявить динамический список:

 Item * dlist = new Item[2];
  

Установите их:

 dlist[0] = i1;
dlist[1] = i2;
  

затем передайте их в вашу функцию:

 setInteractable(dlist);
  

Наконец, вы должны не забыть очистить свою память:

 delete [] dlist;
  

Или… вы делаете это с помощью стандартной библиотеки шаблонов.

 std::vector<Item> temp1;

temp1.push_back(i1);
//... other sets
  

Ваша функция должна быть:

 void setInteractable(std::vector<Item> amp; list)
{
///
}
  

Вызов должен быть

 setInteractable(temp1);
  

Ответ №3:

Это неправильный синтаксис C для передачи подобной инициализации массива:

 i1.setInteractable({i2,i3}); // error: invalid
  

Вы можете достичь этого различными способами. Самый простой способ — использовать std::vector .
Сначала объявите interactableItems как,

 static vector<Item> interactableItems;
  

Теперь вам не нужно setInteractable() , если вы создадите вышеуказанную переменную public
Использование:

 i1.interactableItems.push_back(Item("Item 2"));
i1.interactableItems.push_back(Item("Item 3"));
  

Если вы хотите иметь переменную, private тогда вы можете просто создать оболочку и поместить push_back внутрь нее.

Комментарии:

1. Смотрите, это создавало бы новую копию элемента каждый раз, когда он добавляет его в список взаимодействия с другим элементом. Ему нужно передать ссылку (или указатель) на данный элемент каждому другому элементу. Я предполагаю, что если один элемент взаимодействует с другим, это потенциально может повлиять и на другие, чего этот код не смог бы сделать.

2. Я понимаю, что я создаю копию элемента, однако, если два элемента взаимодействуют, они просто удаляются из инвентаря и добавляется новый комбинированный элемент. Таким образом, даже если у нас есть копии исходного элемента, это на самом деле не имеет значения (это может быть проблема с памятью, но поскольку это не крупномасштабный проект, это действительно не будет иметь значения).

Ответ №4:

Я бы решил проблему следующим образом:

Измените метод, чтобы он работал с одним объектом за раз, и выполняйте цикл над ними:

 void setInteractable(Item amp;i);

for (int i = 0; i < 25; i  )
   for (int j = i   1; j < 25; j  )
      items[i].setInteractable(items[j]);
  

Гораздо проще иметь дело. Вы можете сохранить их в std::vector внутри элемента, и только с ними.

Комментарии:

1. С вашим решением вы сформируете группу объектов. Вопрос не обязательно требует, чтобы все объекты взаимодействовали друг с другом.

Ответ №5:

Я бы предложил использовать один из контейнеров STL. Моя реализация будет продолжаться таким образом:

// Заголовок метода для метода setInteractable

 #include <vector>

class Item {
private:
// some declarations
public:
    void setInteractable(vector<Item amp;>);
    // some other declarations
};
  

Ваша реализация должна выборочно помещать Item объекты в векторы, прежде чем передавать их в функцию.

Обратитесь к справочному сайту Cplusplus для получения дополнительной информации о контейнерах STL.