如何复制vector中已有对象填充剩余位置并为每个对象分配0-50唯一ID?
解决Vector填充与唯一ID分配问题
看起来你现在的核心问题是:用已有的5个对象作为模板填充vector剩余位置,但直接赋值会导致对象ID重复,而且原代码还有索引越界的风险。我来给你梳理下解决方案:
先说说你原代码的问题
你的代码 for (int i = 5; i <= CParams::iNumBirds; i++){ m_vpDisplayableObjects[i + 5] = m_vpDisplayableObjects[i]; } 有两个明显的问题:
- 索引越界:当
i接近CParams::iNumBirds时,i+5很容易超过vector的50容量限制,直接触发未定义行为。 - ID重复:如果
m_vpDisplayableObjects是指针容器,赋值后多个元素会指向同一个对象实例,ID自然完全相同;如果是值类型容器,复制后的对象ID会和模板对象一致,也不符合唯一ID的要求。
针对不同容器类型的解决方案
情况1:容器存储的是值类型对象
如果你的DisplayableObject是值类型(非指针),可以直接复制对象内容后修改ID:
// 假设对象有public的id成员,或者setID()方法 int currentUniqueId = 5; // 假设前5个对象的ID是0-4,从5开始分配 const int totalSize = 50; const int existingCount = 5; // 填充剩余的45个位置 for (int i = existingCount; i < totalSize; ++i) { // 循环使用前5个对象作为模板 int templateIndex = i % existingCount; // 复制模板对象的内容 m_vpDisplayableObjects[i] = m_vpDisplayableObjects[templateIndex]; // 设置唯一ID m_vpDisplayableObjects[i].id = currentUniqueId++; // 如果用方法的话:m_vpDisplayableObjects[i].setID(currentUniqueId++); }
这样每个新复制的对象都会拿到从5到49的唯一ID,刚好覆盖50个对象的0-49范围。
情况2:容器存储的是对象指针
如果是指针容器,直接赋值指针会导致多个元素指向同一个对象,必须深拷贝每个模板对象,再设置新ID:
// 假设你的对象类有clone()方法(用于创建深拷贝)和setID()方法 int currentUniqueId = 5; const int totalSize = 50; const int existingCount = 5; // 确保vector已经预留了足够空间(或者用push_back扩展) m_vpDisplayableObjects.reserve(totalSize); // 先遍历已有模板对象,每个模板复制对应次数(5个模板各复制9次,刚好45个) int copiesPerTemplate = (totalSize - existingCount) / existingCount; for (int templateIdx = 0; templateIdx < existingCount; ++templateIdx) { for (int copyIdx = 0; copyIdx < copiesPerTemplate; ++copyIdx) { // 深拷贝模板对象 DisplayableObject* newObj = m_vpDisplayableObjects[templateIdx]->clone(); // 设置唯一ID newObj->setID(currentUniqueId++); // 添加到容器中 m_vpDisplayableObjects.push_back(newObj); } }
如果你的vector是固定大小50(已经初始化好容量),也可以直接通过索引赋值:
int currentIdx = existingCount; for (int templateIdx = 0; templateIdx < existingCount; ++templateIdx) { for (int copyIdx = 0; copyIdx < copiesPerTemplate; ++copyIdx) { DisplayableObject* newObj = m_vpDisplayableObjects[templateIdx]->clone(); newObj->setID(currentUniqueId++); m_vpDisplayableObjects[currentIdx++] = newObj; } }
额外说明:处理已有ID不连续的情况
如果前5个对象的ID不是0-4,而是随机的,那需要先收集已使用的ID,再分配未使用的唯一ID:
#include <unordered_set> // 先收集已有的ID std::unordered_set<int> usedIds; for (const auto& obj : m_vpDisplayableObjects) { usedIds.insert(obj.id); // 如果是指针就是obj->id } int currentUniqueId = 0; const int totalSize = 50; const int existingCount = 5; for (int i = existingCount; i < totalSize; ++i) { // 找到下一个未被使用的ID while (usedIds.count(currentUniqueId)) { currentUniqueId++; } // 复制模板对象并设置ID int templateIndex = i % existingCount; m_vpDisplayableObjects[i] = m_vpDisplayableObjects[templateIndex]; m_vpDisplayableObjects[i].id = currentUniqueId; usedIds.insert(currentUniqueId); currentUniqueId++; }
这样就能保证所有50个对象都拥有0到49之间的唯一ID啦。
内容的提问来源于stack exchange,提问作者MR.JD
相关产品推荐
相关产品推荐

