Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/3: Рейтинг темы: голосов - 3, средняя оценка - 4.67
0 / 0 / 0
Регистрация: 02.11.2023
Сообщений: 22

Создание системы инвентаря-проблема с цикличным включением заголовочных файлов

02.11.2023, 22:16. Показов 719. Ответов 4

Студворк — интернет-сервис помощи студентам
Начну с очевидного, я новичок в С++, совсем недавно освоил самую базу и многие вещи, которые я написал в коде, возможно могут показаться глупыми или странными (я возможно даже знаю что).

Вообщем, хотел я сделать небольшую игрушку по типу Зельды на SFML. Я хотел реализовать там более сложную систему инвентаря и большое разнообразие предметов, поэтому создал специальный класс Item. От Item наследуется абстрактный класс Potion (зелья), а уже от него все классы разных зелий (да, у каждого зелья есть свой класс). Я не знаю приемлемо ли так писать или нет, но лично для меня это выглядит странно, создавать целый класс для одного зелья, но я все равно решил оставить как есть, но столкнулся с проблемой цикличного включения заголовочных файлов.

У меня есть два класса, Item и Player. Идея заключалась в том, что бы создать массив объектов Item в классе Player, что как бы и являлось инвентарем. Для этого мне пришлось подключить в Player.h заголовок Item.h. В Potion есть виртуальная функция Use, которую должны переопределять все последующие классы зелий наследуемые от него. Они должны менять характеристики Player и для этого я подключил уже Player.h в Item.h. ТУТ И ПОЯВЛЯЕТСЯ ЭТА ОШИБКА!
Ошибка C3646 Inventory: неизвестный спецификатор переопределения

Уже не знаю то делать, видел какой то похожий вопрос на форуме, но то ли я слишком тупой, что если появляется больше 10 строчек кода, то я уже не понимаю что там происходит, то ли это немного не тот случай, тк там подключались не заголовочные файлы, а сразу cpp.(я не уверен, что там есть разница) Это ошибка встречается мне не в первый раз, но я всегда пытался ее обойти какими нибудь всратыми костылями.

Я максимально упростил код и убрал все лишнее, не могли бы вы мне объяснить, как сделать так, "что бы работало"...

Player.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#pragma once
#include <iostream>
#include "Item.h"
 
class Player
{
    int hp;
    int speed;
    Item Inventory[20];
public:
    int getHp();
    int getSpeed();
 
    void setHp(int hp);
    void setSpeed(int speed);
};
Item.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#pragma once
#include "Player.h"
class Item
{};
class Potion :Item
{
    virtual void USE(Player & player) = 0;
public:
};
class HealthPotion :Potion
{
public:
    void USE(Player&player)override;
};
Item.cpp
C++
1
2
3
4
5
6
#include "Item.h"
 
void HealthPotion::USE(Player&player)
{
    player.setHp(player.getHp() + 20);
}
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
02.11.2023, 22:16
Ответы с готовыми решениями:

Система инвентаря. Проблема с отрисовкой инвентаря, несмотря на то, что логика работает как надо
Недавно начал изучать работу в Unity и С# с нуля. Долго мучился с системой предметов, но что-то таки соорудил. Появилась одна проблема:...

Создание инвентаря в Unity. Проблема с проектированием
Всем добрый день! Я занимаюсь разработкой игры на Unity, и возникла проблема, которую я не знаю как решить без создания костылей,...

Создание и использование заголовочных файлов
Здравствуйте! Хочу создать заголовочный файл и засунуть туда объявления функций. Так он выглядит #ifndef LONGNUM_H_INCLUDED #define...

4
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
02.11.2023, 23:04
Цитата Сообщение от Rekava Посмотреть сообщение
я новичок в С++
...
хотел я сделать небольшую игрушку по типу Зельды на SFML
Ничего себе планы.

У тебя неправильная структура классов. Если Player владеет Item'ами, то он ими и управляет, а не наоборот.
И если там просто массив, то полиморфизм бесполезен.
1
0 / 0 / 0
Регистрация: 02.11.2023
Сообщений: 22
02.11.2023, 23:17  [ТС]
На счет планов, я говорил о самой первой зелде (на nes).

Я попробую изменить логику, но не могли бы объяснить как вообще избежать такой ошибки? Я думал что проблему повторного включения решает #pragma once...
0
 Аватар для eva2326
1673 / 501 / 107
Регистрация: 17.05.2015
Сообщений: 1,518
02.11.2023, 23:29
Лучший ответ Сообщение было отмечено Rekava как решение

Решение

Цитата Сообщение от Rekava Посмотреть сообщение
Item.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#pragma once
 
class Player;
 
class Item
{};
class Potion :Item
{
    virtual void USE(Player & player) = 0;
public:
};
class HealthPotion :Potion
{
public:
    void USE(Player&player)override;
};
Цитата Сообщение от Rekava Посмотреть сообщение
Item.cpp
C++
1
2
3
4
5
6
7
#include "Item.h"
#include "Player.h"
 
void HealthPotion::USE(Player&player)
{
    player.setHp(player.getHp() + 20);
}
Цитата Сообщение от Rekava Посмотреть сообщение
#include "Item.h"
class Player
{
    int hp;
    int speed;
    Item Inventory[20];
Если выкинуть массив, тогда можно будет избавиться от зависимости #include "Item.h"

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <list>
 
class Item;
 
class Player
{
    int hp;
    int speed;
    std::list<Item> Inventory;
public:
    int getHp();
    int getSpeed();
 
    void setHp(int hp);
    void setSpeed(int speed);
};
1
0 / 0 / 0
Регистрация: 02.11.2023
Сообщений: 22
02.11.2023, 23:34  [ТС]
Спасибо!
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
02.11.2023, 23:34
Помогаю со студенческими работами здесь

Создание иерархии заголовочных файлов
Есть класс, который принимает строку типа &quot;analyser /home/hhh/fold -I /home/hhh/includes&quot; Этот класс добавляет нужные файлы в...

Про добавление заголовочных файлов в заголовочных файлах
В который раз эта вещь засовывает мозги в блендер! Я про то, что не могу однозначно запомнить (основываясь на моих знаниях о директиве...

Проблема с цикличным привязыванием событий
import tkinter as tk def entry_process(event, name): print(name) root = tk.Tk() entrys = {'0': tk.Entry(root,...

Раздельная компиляция (нюансы использования заголовочных файлов и файлов реализации)
Почему во многих учебниках функции-члены класса внутри класса только объявляют, но определяют вне самого класса (не, ну как бы в классе, но...

Выложите пожалуйста простейший пример содания файлов описания и заголовочных файлов с дальнейшим их подключением.
собственно сабж.Просто в книге есть пример, но он у меня не работает. Добавлено через 20 минут ни кто не поможет? я уже кучу книг...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Новые блоги и статьи
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru