С Новым годом! Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.50/4: Рейтинг темы: голосов - 4, средняя оценка - 4.50
7 / 6 / 1
Регистрация: 29.10.2016
Сообщений: 175
1

Ошибка: нет доступа к полю класса

14.03.2020, 14:32. Показов 807. Ответов 8
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Доброго.

Пишу подобие ECS, и не могу понять, почему когда система обрабатывает компоненты сущности, она не изменяет их?
Все отрабатывает, но поле а_ класса ComponentA остается = 0, а ожидается 1.

Полный код ниже:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
#include <iostream>
#include <map>
#include <string>
#include <typeindex>
#include <vector>
#include <set>
#include <type_traits>
#include <algorithm>
 
using namespace std;
 
class Component
{
protected:
    size_t componentID_{ 0 };
public:
    size_t getComponentID() {
        return componentID_;
    }
    virtual ~Component() = default;
};
 
class Entity
{
private:
    std::map<size_t, Component*> components_;
    std::string entityName_{};
    size_t idEntity_{ 0 };
public:
 
    //TODO: Добавить activate/deactivate
 
    void setEntityName(const std::string entityName)
    {
        entityName_ = entityName;
    }
 
    const std::string getEntityName() {
        return entityName_;
    }
 
    void setID(const size_t id)
    {
        idEntity_ = id;
    }
 
    const size_t getID()
    {
        return idEntity_;
    }
 
    const bool containComponent(size_t componentID) 
    {
        for (auto component : components_) {
            if (component.second->getComponentID() == componentID) {
                return true;
            }
        }
        return false;
    }
 
    std::vector<size_t> getContainsComponentsID() const {
        std::vector<size_t> resultVector;
        std::transform(components_.cbegin(), components_.cend(), std::back_inserter(resultVector), [](auto&& arg) { return arg.first; });
        return resultVector;
    }
 
    Component* getComponent(size_t componentID)
    {
        for (auto component : components_) {
            if (component.second->getComponentID() == componentID) {
                auto poiner = components_.at(componentID);
                return poiner;
            }
        }
    }
 
    template<typename TComponent>
    void addComponent(TComponent* addingComponent)
    {
        components_[addingComponent->getComponentID()] = addingComponent;
    }
 
    template<typename TComponent>
    void createComponent()
    {
        TComponent* buff = new TComponent();
        components_[buff->getComponentID()] = buff;
    }
    
    void removeComponent(size_t removingID) 
    {
        components_.erase(removingID);
    }
 
    const size_t howManyComponents() {
        return components_.size();
    }
 
    void removeAllComponents()
    {
        components_.clear();
    }
 
    virtual ~Entity() {
        removeAllComponents();
    };
 
};
 
class System
{
private:
    std::set<size_t> processedComponents_;
    size_t idSystem_{ 0 };
public:
 
    void setID(size_t value) 
    {
        idSystem_ = value;
    }
 
    const size_t getID() 
    {
        return idSystem_;
    }
 
    void addProcessedComponent(size_t addingComponentID)
    {
        processedComponents_.insert(addingComponentID);
    }
 
    void removeProcessedComponent(size_t removingComponentID)
    {
        processedComponents_.erase(removingComponentID);
    }
 
    const bool containProcessedComponent(size_t componentID)
    {
        return processedComponents_.count(componentID) != 0;
    }
 
    std::vector<size_t> getProcessedComponentsID() const {
        std::vector<size_t> resultVector(processedComponents_.begin(), processedComponents_.end());
        return resultVector;
    }
 
    ~System() {
        processedComponents_.clear();
    };
 
    
    virtual void updateSystem(Entity*) {};
};
 
class World
{
private:
    std::map<size_t, System*> systems_;
    std::map<size_t, Entity*> entities_;
    std::multimap<size_t, size_t> pairSysIDEntID_;
    size_t lastEntityID_{ 0 };
public:
 
    //TODO: Добавить activate/deactivate
 
    size_t getLastEntityID()
    {
        return lastEntityID_;
    }
 
    template <typename TEntity>
    void addEntity(TEntity* addingEntity)
    {
        if (addingEntity->getID() == (size_t)0)
        {
            addingEntity->setID(++lastEntityID_);
        }
        else {
            lastEntityID_ = addingEntity->getID();
        }
        entities_[addingEntity->getID()]=addingEntity;
    }
 
    template <typename TEntity>
    void createEntity()
    {
        TEntity* buff = new TEntity();
        entities_[++lastEntityID_]= buff;
    }
 
    //template <typename TEntity>
    void purgeEntity(size_t purgingEntityID)
    {
        size_t keyOfPurgingEntity(0);
        for (auto it = entities_.begin(); it!=entities_.end(); ++it)
        {
            if (it->second->getID() == purgingEntityID) {
                keyOfPurgingEntity = it->first;
                break;
            }
        }
        entities_.erase(keyOfPurgingEntity);
    }
 
    void clearEntities() {
        entities_.clear();
    }
 
    template <typename TSystem>
    void addSystem(TSystem* addingSystem)
    {
        systems_[addingSystem->getID()] = addingSystem;
    }
 
    template <typename TSystem>
    void createSystem()
    {
        TSystem* newSystem = new TSystem();
        systems_[newSystem->getID()] = newSystem;
    }
 
    template<typename TSystem>
    TSystem* getSystem(size_t gettingSystemID) const {
        auto pointer = systems_.at(gettingSystemID);
        return pointer;
    }
 
 
    template<typename TSystem>
    void purgeSystem(size_t purgingSystemID)
    {
        systems_.erase(purgingSystemID);
    }
 
 
    void updateWorldList()
    {
        for (auto it = systems_.begin(); it != systems_.end(); ++it)
        {
            std::vector<size_t> componentsInsideSystem = it->second->getProcessedComponentsID();
            for (auto jt = entities_.begin(); jt != entities_.end(); ++jt)
            {
                bool containsAll = true;
                for (size_t i = 0; i < componentsInsideSystem.size(); i++)
                {
                    if (!jt->second->containComponent(componentsInsideSystem[i])) {
                        containsAll = false;
                    }
                }
 
                if (containsAll) 
                {
                    pairSysIDEntID_.insert(std::pair<size_t, size_t>(it->first, jt->first));
                }
 
            }
        }
    }
 
    void refreshWorld()
    {
        for (auto it = pairSysIDEntID_.begin(); it != pairSysIDEntID_.end(); ++it)
        {
            systems_.at(it->first)->updateSystem(entities_.at(it->second));
        }
    }
 
    void clearWorld() {
        for (auto& systems : systems_) {
            systems.second->~System();
        }
        entities_.clear();
        systems_.clear();
    }
 
    ~World() {
        clearWorld();
    };
};
 
 
/*TEST*/
 
class ComponentA : public Component {
public:
    int a{0};
    ComponentA() {
        componentID_ = 1;
    }
};
 
class ComponentB : public Component {
public:
    int b{ 0 };
    ComponentB() {
        componentID_ = 2;
    }
};
 
class FirstEntity : public Entity {
public:
    FirstEntity() {
        setEntityName("First");
        //addComponent(new ComponentA);
    }
};
 
class PrimarySystem : public System {
public:
    PrimarySystem() {
        setID(1);
        addProcessedComponent(1);
    }
 
    void updateSystem(Entity* ent) override{
        auto comp = ent->getComponent(1);
        comp++;
    }
};
 
int main()
{
    World* world = new World();
    PrimarySystem* sys = new PrimarySystem();
    FirstEntity* ent = new FirstEntity();
    ent->createComponent<ComponentA>();
    ent->createComponent<ComponentB>();
    world->addSystem(sys);
    world->addEntity(ent);
    world->updateWorldList();
 
    world->refreshWorld();
 
    system("pause");
    delete ent;
    delete sys;
    delete world;
    
    
    return 0;
}
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
14.03.2020, 14:32
Ответы с готовыми решениями:

Нет доступа к инициализованному полю
Собственно проблема в следующем: в программе генерируются точки с случайно заданными координатами,...

Нет доступа к полю private
Всем доброго дня ! Полскажите пожалуйста почему обьект nak не может получить доступ к функции...

Получения доступа к полю другого класса
Доброго времени суток. Сделав всю работу осталось только, чтобы на разные радио-кнопки совершались...

Определение класса leverage и метода для доступа к закрытому полю
Напишите определение класса leverage, включающего одно закрытое поле типа int с именем crowbar....

8
"C with Classes"
2022 / 1404 / 523
Регистрация: 16.08.2014
Сообщений: 5,884
Записей в блоге: 1
14.03.2020, 14:46 2
Цитата Сообщение от Battary Посмотреть сообщение
но поле а_ класса ComponentA остается = 0, а ожидается 1.
ты это поле инициализируешь нулем:
C++
1
2
public:
    int a{0};
а где ты ему присваиваешь единицу которая ожидается я не нашел, покажи.
И зачем весь код скидывать, если большая часть не нужна. То есть ты поленился не локализовал ошибку, а кто за тебя на форуме будет разгребать все это хозяйство?
0
Эксперт С++
8972 / 4318 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
14.03.2020, 14:46 3
я бы на твоём месте для начала исправил очевидные косяки:

Код
source_file.cpp: In member function ‘Component* Entity::getComponent(size_t)’:
source_file.cpp:76:5: warning: control reaches end of non-void function [-Wreturn-type]
Код
source_file.cpp:337:12: warning: deleting object of polymorphic class type ‘PrimarySystem’ which has non-virtual destructor might cause undefined behaviour [-Wdelete-non-virtual-dtor]
     delete sys;
остальные не критичны, но неприятны:

Код
Warning(s):
source_file.cpp:47:24: warning: type qualifiers ignored on function return type [-Wignored-qualifiers]
     const size_t getID()
                        ^
source_file.cpp:52:51: warning: type qualifiers ignored on function return type [-Wignored-qualifiers]
     const bool containComponent(size_t componentID) 
                                                   ^
source_file.cpp:96:36: warning: type qualifiers ignored on function return type [-Wignored-qualifiers]
     const size_t howManyComponents() {
                                    ^
source_file.cpp:123:24: warning: type qualifiers ignored on function return type [-Wignored-qualifiers]
     const size_t getID() 
                        ^
source_file.cpp:138:60: warning: type qualifiers ignored on function return type [-Wignored-qualifiers]
     const bool containProcessedComponent(size_t componentID)
                                                            ^
source_file.cpp:111:7: warning: ‘class System’ has virtual functions and accessible non-virtual destructor [-Wnon-virtual-dtor]
 class System
       ^
source_file.cpp: In member function ‘void World::addEntity(TEntity*)’:
source_file.cpp:175:46: warning: use of old-style cast [-Wold-style-cast]
         if (addingEntity->getID() == (size_t)0)
                                              ^
source_file.cpp: In constructor ‘Entity::Entity()’:
source_file.cpp:23:7: warning: ‘Entity::components_’ should be initialized in the member initialization list [-Weffc++]
 class Entity
       ^
source_file.cpp: In constructor ‘FirstEntity::FirstEntity()’:
source_file.cpp:303:19: note: synthesized method ‘Entity::Entity()’ first required here 
     FirstEntity() {
                   ^
source_file.cpp: At global scope:
source_file.cpp:309:7: warning: base class ‘class System’ has accessible non-virtual destructor [-Wnon-virtual-dtor]
 class PrimarySystem : public System {
       ^
source_file.cpp:309:7: warning: ‘class PrimarySystem’ has virtual functions and accessible non-virtual destructor [-Wnon-virtual-dtor]
source_file.cpp: In constructor ‘System::System()’:
source_file.cpp:111:7: warning: ‘System::processedComponents_’ should be initialized in the member initialization list [-Weffc++]
 class System
       ^
source_file.cpp: In constructor ‘PrimarySystem::PrimarySystem()’:
source_file.cpp:311:21: note: synthesized method ‘System::System()’ first required here 
     PrimarySystem() {
                     ^
source_file.cpp: In constructor ‘World::World()’:
source_file.cpp:156:7: warning: ‘World::systems_’ should be initialized in the member initialization list [-Weffc++]
 class World
       ^
source_file.cpp:156:7: warning: ‘World::entities_’ should be initialized in the member initialization list [-Weffc++]
source_file.cpp:156:7: warning: ‘World::pairSysIDEntID_’ should be initialized in the member initialization list [-Weffc++]
source_file.cpp: In function ‘int main()’:
source_file.cpp:324:30: note: synthesized method ‘World::World()’ first required here 
     World* world = new World();
                              ^
source_file.cpp:337:12: warning: deleting object of polymorphic class type ‘PrimarySystem’ which has non-virtual destructor might cause undefined behaviour [-Wdelete-non-virtual-dtor]
     delete sys;
            ^
source_file.cpp:335:20: warning: ignoring return value of ‘int system(const char*)’, declared with attribute warn_unused_result [-Wunused-result]
     system("pause");
                    ^
source_file.cpp: In member function ‘Component* Entity::getComponent(size_t)’:
source_file.cpp:76:5: warning: control reaches end of non-void function [-Wreturn-type]
     }
     ^
0
7 / 6 / 1
Регистрация: 29.10.2016
Сообщений: 175
14.03.2020, 14:53  [ТС] 4
Цитата Сообщение от _stanislav Посмотреть сообщение
ты это поле инициализируешь нулем:
C++
1
2
public:
    int a{0};
а где ты ему присваиваешь единицу которая ожидается я не нашел, покажи.
И зачем весь код скидывать, если большая часть не нужна. То есть ты поленился не локализовал ошибку, а кто за тебя на форуме будет разгребать все это хозяйство?
C++
1
2
3
4
5
6
7
8
9
10
11
12
class PrimarySystem : public System {
public:
    PrimarySystem() {
        setID(1);
        addProcessedComponent(1);
    }
 
    void updateSystem(Entity* ent) override{
        auto comp = ent->getComponent(1);
        comp++;
    }
};
Как раз comp++ и должен делать из 0 единицу.

Добавлено через 1 минуту
Цитата Сообщение от hoggy Посмотреть сообщение
я бы на твоём месте для начала исправил очевидные косяки:
остальные не критичны, но неприятны:
Компилятор компилятору рознь, спасибо, поправлю.
0
6340 / 3511 / 1427
Регистрация: 07.02.2019
Сообщений: 8,977
14.03.2020, 14:57 5
Цитата Сообщение от Battary Посмотреть сообщение
Как раз comp++ и должен делать из 0 единицу.
comp у тебя имеет тип Component*, из какого нуля ты единицу делаешь?
0
7 / 6 / 1
Регистрация: 29.10.2016
Сообщений: 175
14.03.2020, 15:06  [ТС] 6
Цитата Сообщение от zayats80888 Посмотреть сообщение
comp у тебя имеет тип Component*, из какого нуля ты единицу делаешь?
Вы правы, заметил. Ну так он указывает на Component, почему не на ComponentA?
0
Эксперт С++
8972 / 4318 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
14.03.2020, 15:07 7
Цитата Сообщение от Battary Посмотреть сообщение
Компилятор компилятору рознь, спасибо, поправлю.
если ты вдруг не понял: у тебя в коде ошибки.
и это не зависит от компиляторов.

например:

C++
1
2
3
4
5
6
7
8
9
10
Component* getComponent(size_t componentID)
    {
        for (auto component : components_) {
            if (component.second->getComponentID() == componentID) {
                auto poiner = components_.at(componentID);
                return poiner;
            }
        }
       // <---- отсутствует return
    }
функция возвращает значения не на всех ветках выполнения.
что если нужный componentID так и не будет найден, что тогда вернет функция?

или:

Цитата Сообщение от Battary Посмотреть сообщение
delete sys;
деструктор полиморфного класса для объекта, к которому применяется delete,
должен быть виртуальным. в противном случае поведение не определено.

у тебя во всей твоей иерархии классов нет ни одного виртуального деструктора.

ты вообще понимаешь, зачем нужен виртуальный деструтор,
и какими последствиями грозит его отсутствие?
0
6340 / 3511 / 1427
Регистрация: 07.02.2019
Сообщений: 8,977
14.03.2020, 15:12 8
Цитата Сообщение от Battary Посмотреть сообщение
Ну так он указывает на Component, почему не на ComponentA?
Ты в курсе что такое полиморфизм и как он работает?
Кликните здесь для просмотра всего текста
Цитата Сообщение от Battary Посмотреть сообщение
Компилятор компилятору рознь
И твой код крашится в деструкторе System


Добавлено через 4 минуты
Цитата Сообщение от zayats80888 Посмотреть сообщение
И твой код крашится в деструкторе System
Не удивительно:
C++
1
2
3
4
5
6
7
    void clearWorld() {
        for (auto& systems : systems_) {
            systems.second->~System(); // <---???
        }
        entities_.clear();
        systems_.clear();
    }
0
7 / 6 / 1
Регистрация: 29.10.2016
Сообщений: 175
14.03.2020, 15:55  [ТС] 9
Цитата Сообщение от hoggy Посмотреть сообщение
деструктор полиморфного класса для объекта, к которому применяется delete,
должен быть виртуальным. в противном случае поведение не определено.

у тебя во всей твоей иерархии классов нет ни одного виртуального деструктора.

ты вообще понимаешь, зачем нужен виртуальный деструтор,
и какими последствиями грозит его отсутствие?
Уже исправлено. Да, я в курсе, что происходит, когда поведение не определено (обычно часть объекта, принадлежащая производному классу никогда не будет уничтожена).

World не имеет виртуального деструктора потому что не не подразумевается, что он будет использован как базовый.

Добавлено через 34 минуты
Я просто не знаю как написать...как получить доступ к полям ComponentA?
0
14.03.2020, 15:55
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
14.03.2020, 15:55
Помогаю со студенческими работами здесь

Ошибка доступа к полю
#include &lt;iostream&gt; using namespace std; int i = 0; class CDate { protected: int Year;...

Ошибка доступа к полю в БД Paradox
Нужно реализовать работу приложения в Делфи с помощью BDE и Paradox (да-да, с помощью этого дерьма,...

Windows XP нет доступа к сети, нет доступа к Norton антивирус, сетевых служб нет
Отключился Инет, попробовал загрузить сетевые подключения - нет ни одной иконки. Загрузился с...

Нет доступа до переменных класса
Здравствуйте. Делаю лабораторную и столкнулся с такой проблемой. Создал модуль с такой информацией:...


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

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Новые блоги и статьи
Книги и учебные ресурсы по C#
InfoMaster 08.01.2025
Базовые учебники и руководства Одной из лучших книг для начинающих является "C# 10 и . NET 6 для начинающих" Эндрю Троелсена и Филиппа Джепикса . Книга последовательно раскрывает основные концепции. . .
Что такое NullReferenceEx­­­ception и как исправить?
InfoMaster 08.01.2025
NullReferenceException - одно из самых распространенных исключений, с которым сталкиваются разработчики на C#. Это исключение возникает при попытке обратиться к членам объекта (методам, свойствам или. . .
Что такое Null Pointer Exception (NPE) и как это исправить?
InfoMaster 08.01.2025
Null Pointer Exception (NPE) - это одно из самых распространенных исключений в Java, которое возникает при попытке использовать ссылку на объект, значение которой равно null. Это исключение относится. . .
Русский язык в консоли C++
InfoMaster 08.01.2025
При разработке программ на C++ одной из частых проблем, с которой сталкиваются русскоязычные программисты, является корректное отображение кириллицы в консольных приложениях. Эта проблема особенно. . .
Telegram бот на C#
InfoMaster 08.01.2025
Разработка ботов для Telegram стала неотъемлемой частью современной экосистемы мессенджеров. C# предоставляет мощный и удобный инструментарий для создания разнообразных ботов, от простых. . .
Использование GraphQL в Go (Golang)
InfoMaster 08.01.2025
Go (Golang) является одним из наиболее популярных языков программирования, используемых для создания высокопроизводительных серверных приложений. Его архитектурные особенности и встроенные. . .
Что лучше использовать при создании класса в Java: сеттеры или конструктор?
Alexander-7 08.01.2025
Вопрос подробнее: На вопрос: «Когда одновременно создаются конструктор и сеттеры в классе – это нормально?» куратор уточнил: «Ваш класс может вообще не иметь сеттеров, а только конструктор и геттеры. . .
Как работать с GraphQL на TypeScript
InfoMaster 08.01.2025
Введение в GraphQL и TypeScript В современной разработке веб-приложений GraphQL стал мощным инструментом для создания гибких и эффективных API. В сочетании с TypeScript, эта технология. . .
Счётчик на базе сумматоров + регистров и генератора сигналов согласования.
Hrethgir 07.01.2025
Создан с целью проверки скорости асинхронной логики: ранее описанного сумматора и предополагаемых fast регистров. Регистры созданы на базе ранее описанного, предполагаемого fast триггера. То-есть. . .
Как перейти с Options API на Composition API в Vue.js
BasicMan 06.01.2025
Почему переход на Composition API актуален В мире современной веб-разработки фреймворк Vue. js продолжает эволюционировать, предлагая разработчикам все более совершенные инструменты для создания. . .
Архитектура современных процессоров
inter-admin 06.01.2025
Процессор (центральный процессор, ЦП) является основным вычислительным устройством компьютера, которое выполняет обработку данных и управляет работой всех остальных компонентов системы. Архитектура. . .
История создания реляционной модели баз данных, правила Кодда
Programming 06.01.2025
Предпосылки создания реляционной модели В конце 1960-х годов компьютерная индустрия столкнулась с серьезными проблемами в области управления данными. Существовавшие на тот момент модели данных -. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru