#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.