我有一个函数,用于将值插入到向量映射的空映射中。 (该特定结构适用于我对渲染对象的一些复杂排序的需要)。
然而,当我向其中添加内容时,我的数据似乎在结构的某个点上丢失了。
我的方法代码(带有一点上下文)在这里:
typedef unsigned int ComponentUID;
//For the purposes of this example, assume the map is completely empty
std::map<ComponentUID, std::map<float, std::vector<GameObjectPtr>>> renderOrderMap;
void Render::addGameObjectToMap(GameObjectPtr objectPtr) {
//Expose the pointer for ease of use
GameObject *object = objectPtr.get();
//Set up component local variables
RenderComponent *component = object->getRenderComponent();
ComponentUID uid = component->getComponentUID();
//Get object's render level (arbitrary float)
float renderLevel = object->getRenderLevel();
//Find the location of the component UID in the render order map
std::map<ComponentUID, std::map<float, std::vector<GameObjectPtr>>>::iterator objectLocation = renderOrderMap.find(uid);
//If the object doesn't exist in the map
if (objectLocation == renderOrderMap.end()) {
//Add a new pair with the component UID and a fresh float/vector map and set the object location to the iterator pointing to it
objectLocation = renderOrderMap.insert(std::pair<ComponentUID, std::map<float, std::vector<GameObjectPtr>>>(uid, std::map<float, std::vector<GameObjectPtr>>())).first;
printf("Inserted pair");
}
//Get the map at the value of the object location iterator
std::map<float, std::vector<GameObjectPtr>> objectMapping = objectLocation->second;
//Find the render level in the map
std::map<float, std::vector<GameObjectPtr>>::iterator vectorLocation = objectMapping.find(renderLevel);
//If the object doesn't exist in the map
if (vectorLocation == objectMapping.end()) {
//Add a new pair with the render level and a fresh GameObjectPtr vector and set the vector location to the pair's iterator
vectorLocation = objectMapping.insert(std::pair<float, std::vector<GameObjectPtr>>(renderLevel, std::vector<GameObjectPtr>())).first;
/*
* These two should equal the same value, because they should call the same method on the same object
*/
printf("Mapping size: %i", objectMapping.size()); //Outputs 1
printf("ExtraMapSize0: %i", renderOrderMap.find(uid)->second.size()); //Outputs 0
}
//Add the game object to the vector
std::vector<GameObjectPtr> objectVector = vectorLocation->second;
objectVector.push_back(objectPtr);
}
问题在于底部有两个printf语句。从理论上讲,它们应指向同一个对象,但第一个调用会向第二个调用返回不同的值。
我的代码是否存在问题,或者我是否从根本上误解了迭代器的工作方式?
答案 0 :(得分:1)
std::map<float, std::vector<GameObjectPtr>> objectMapping = objectLocation->second;
这会将objectLocation->second
复制到名为objectMapping
的新地图中。 objectMapping
是一个新对象,由objectLocation->second
复制构建。
vectorLocation = objectMapping.insert(...
这会在objectMapping
对象中插入一个新值。
/*
* These two should equal the same value, because they should call the same method on the same object
*/
printf("Mapping size: %i", objectMapping.size()); //Outputs 1
printf("ExtraMapSize0: %i", renderOrderMap.find(uid)->second.size()); //Outputs 0
不,他们不是同一个对象。它们是不同的对象。这不是调用相同对象的相同方法,而是调用两个不同的独立对象的相同方法。这就是为什么你没有得到相同的价值。
我猜你最初是一名Java开发人员,而你现在正在学习C ++。这就是对象在Java中的工作方式,但它们在C ++中的工作方式不同。您声明了一个名为objectMapping
的新对象,从另一个对象复制构造它,另一个映射中的值。
如果你真的希望它们是同一个对象,你必须使objectMapping
成为参考。
std::map<float, std::vector<GameObjectPtr>> &objectMapping = objectLocation->second;
答案 1 :(得分:0)
但你不打印同样的东西。
第一个printf
来电打印的objectMapping
大小为std::map
第二个调用从renderOrderMap
打印向量的大小。