C++ 在std::map中存储结构实例
我正在尝试将一些结构映射到其他实例,如下所示:C++ 在std::map中存储结构实例,c++,templates,stl,struct,C++,Templates,Stl,Struct,我正在尝试将一些结构映射到其他实例,如下所示: template <typename T> class Component { public: typedef std::map<EntityID, T> instances_map; instances_map instances; Component() {}; T add(EntityID id) { T* t = new T(); instanc
template <typename T>
class Component {
public:
typedef std::map<EntityID, T> instances_map;
instances_map instances;
Component() {};
T add(EntityID id) {
T* t = new T();
instances[id] = *t;
return *t;
};
};
struct UnitInfos {
int owner_id;
int health;
float x, y;
};
class LogicComponent : public Component<UnitInfos> {};
comp.instance[id];
我得到一个新的breand对象,其属性初始化为默认值
这段代码是否存在固有的问题,或者我是否遗漏了有关问题的信息
根据@aaa建议,我将代码更改为
typedef std::map<EntityID, T> instances_map;
instances_map instances;
T& add(EntityID id) {
instances[id] = T();
return instances[id];
};
info.x的值仍然是0。有什么建议吗
问题是我如何将对LogicComponent的引用存储在另一个类中。使用
LogicComponent logic\u c代码>而不是逻辑组件和逻辑代码>。它现在可以工作了,但我正在地图中存储指针(而不是@aaa的建议)。这是个坏主意吗?可能是这样
T add(EntityID id) {
T* t = new T();
instances[id] = *t;
return *t; // return value and map instance are not the same anymore
};
应该是
T& add(EntityID id) {
instances[id] = T();
return instances[id];
};
听起来您将索引运算符定义为:
template <typename T>
T& Component::operator[]( EntityID id )
{
return instances[id];
}
这样,当您尝试通过不存在的键进行检索时,将出现异常。更好的是,只需像下面那样使用typedef
即可:
typedef std::map<EntityID,UnitInfos> EntityUnitMap;
typedef std::map EntityUnitMap;
其他人已经提到,您不需要动态分配对象—您将副本存储在容器中—并且这样做时会泄漏内存。阐明您希望在LogicComponent上执行的操作。假设您正试图实现以下目标:
步骤1:向地图添加新条目:
LogicComponent comp;
EntityID id = 99;
UnitInfos info = comp.add(id);
步骤2:初始化信息:
info.x = 10.0;
info.y = 11.0
// etc
步骤3:再次获取信息对象:
UnitInfos info2 = comp.instances[id]; // this is uninitialized.
然后,依次列出一些代码注释:
comp.add返回的信息对象是您添加到地图中的对象的副本。通过修改它,您并不是在修改地图中的内容
最简单的修复方法是创建指向对象的指针映射,而不是对象本身
typedef std::map<EntityID, T*> pinstances_map;
T * add(EntityID id) {
T* t = new T();
instances[id] = t;
return t;
};
// initialize as
UnitInfo *info = comp.add(id);
info->x = 10.0;
info->y = 11.0;
// retrieve as
UnitInfos *info = comp.instances[id];
typedef std::map pinstances\u map;
T*add(EntityID){
T*T=新的T();
实例[id]=t;
返回t;
};
//初始化为
UnitInfo*info=comp.add(id);
信息->x=10.0;
信息->y=11.0;
//检索为
UnitInfo*信息=组件实例[id];
另外,请使用访问器方法获取映射值,而不是将映射对象公开为公共对象。使实例变量受保护,并添加一个public get()方法
编辑:这段代码对我来说很好:
#include <map>
#include <iostream>
using namespace std;
template<typename T>
class Component
{
public:
typedef map<long, T*> pinstances_map;
pinstances_map instances;
T * add(long id)
{
T *t = new T();
instances[id] = t;
return t;
}
};
struct UnitInfo
{
float x, y;
};
class LogicComponent: public Component<UnitInfo> {};
int main()
{
LogicComponent comp;
UnitInfo *info = comp.add(99);
info->x = 10.0;
info->y = 11.0;
UnitInfo *info2 = comp.instances[99];
cout << info2->x << " " << info2->y;
return 0;
}
#包括
#包括
使用名称空间std;
模板
类组件
{
公众:
typedef映射pinstances\u映射;
pinstances\u映射实例;
T*添加(长id)
{
T*T=新的T();
实例[id]=t;
返回t;
}
};
结构单元信息
{
浮动x,y;
};
类LogicComponent:公共组件{};
int main()
{
逻辑元件组件;
UnitInfo*info=comp.add(99);
信息->x=10.0;
信息->y=11.0;
UnitInfo*info2=组件实例[99];
这段代码本身就有问题:不要动态创建t
。没有理由这样做,正如现在编写的那样,您泄漏了该对象。至于您看到的问题,您需要发布EntityID
的小于运算符实现,以及如何调用运算符[]
在地图上(即,如何创建传递给操作符[]
?)的id。EntityID只是定义为typedef unsigned long EntityID;
。我尝试更改代码,但仍然会遇到同样的问题。我是否应该像这样检索实例:UnitInfo=logic\u c.instances[id];
?@sharvey不,unitinfo
是一个新实例,unitinfo&info
是对现有实例的引用。如果您来自Java,您可能需要阅读以下内容:我确实来自Java背景。奇怪的是,当我在更改它之后立即访问它时,值是正确的;但当我稍后再次获得它时,tX的值仍然是0。我会更新这个问题。谢谢。谢谢,我现在明白为什么C++ FAQ Lite说你可能不需要在C++中使用指针。我不认为它也会应用到这样的事情。我正在访问实例子字段,所以我没有[]。组件模板上调用了运算符。当然,我可能错了。我将绝对实现运算符[]就像你建议的,因为它更好。谢谢。你所描述的正是我想要实现的。切换到你所描述的是我想我尝试过的,但是当在你最后一行之后调用info->x时,我得到了一个EXC\u BAD\u访问,信息指向0x0。我同意,这段代码是有效的。当我尝试从代码的另一部分访问它时(渲染函数传递给glutDisplayFunc
和glutIdleFunct
,指针仍然指向0x0。您正在访问同一个LogicComp对象吗?不,我没有。我有一个类成员存储定义为LogicComponent logic\u c;
的LogicComponent。将其更改为LogicComponent&logic\u c;
修复了它!谢谢太多了。
typedef std::map<EntityID, T*> pinstances_map;
T * add(EntityID id) {
T* t = new T();
instances[id] = t;
return t;
};
// initialize as
UnitInfo *info = comp.add(id);
info->x = 10.0;
info->y = 11.0;
// retrieve as
UnitInfos *info = comp.instances[id];
#include <map>
#include <iostream>
using namespace std;
template<typename T>
class Component
{
public:
typedef map<long, T*> pinstances_map;
pinstances_map instances;
T * add(long id)
{
T *t = new T();
instances[id] = t;
return t;
}
};
struct UnitInfo
{
float x, y;
};
class LogicComponent: public Component<UnitInfo> {};
int main()
{
LogicComponent comp;
UnitInfo *info = comp.add(99);
info->x = 10.0;
info->y = 11.0;
UnitInfo *info2 = comp.instances[99];
cout << info2->x << " " << info2->y;
return 0;
}