【发布时间】:2019-06-27 10:50:10
【问题描述】:
我创建了一个类来跟踪具有唯一 ID 的实例。 构造此类的新实例(或复制构造它)提供了一个唯一 ID,该 ID 取自 ID 池。销毁将 ID 放回池中。打印语句观察实例何时被创建和销毁。
#include <iostream>
#include <vector>
#include <list>
class IdPool {
public:
IdPool() {
m_id = allocateID();
std::cout << "c'tor id: " << m_id << std::endl;
}
~IdPool() {
freeID(m_id);
std::cout << "d'tor free id: " << m_id << std::endl;
}
IdPool(const IdPool& obj) {
m_id = allocateID();
std::cout << "copy c'tor id: " << m_id << std::endl;
}
class Init {
public:
Init(const int maxIDs) {
for (int i=maxIDs; i>=1; --i) {
s_idArray.push_back(i);
};
}
};
int id() { return m_id; }
private:
int allocateID() {
if (s_idArray.empty())
return 0;
else {
int id = s_idArray.back();
s_idArray.pop_back();
return id;
}
}
bool freeID(int id) {
if ( (id > 0 ) && (s_idArray.size() < s_maxIdCount) ) {
s_idArray.push_back(id);
return true;
} else {
return false;
}
}
static std::vector<int> s_idArray;
static const size_t s_maxIdCount;
static Init s_setIdCount;
int m_id;
};
const size_t IdPool::s_maxIdCount = 10;
std::vector<int> IdPool::s_idArray;
IdPool::Init IdPool::s_setIdCount(IdPool::s_maxIdCount);
int main(int argc, char* argv[]) {
using namespace std;
cout << endl << "-- push 2 IDs to list --" << endl;
list<IdPool> listId;
for (int i = 0; i < 2; ++i) {
listId.push_back(IdPool());
cout << "push_back to list id: " << listId.back().id() << endl << endl;
}
cout << endl << "-- push 2 IDs to vector --" << endl;
vector<IdPool> vecId;
for (int i = 0; i < 2; ++i) {
vecId.push_back(IdPool());
cout << "push_back to vector id: " << vecId.back().id() << endl << endl;
}
cout << endl << "-- push 2 IDs to preallocated vector --" << endl;
vector<IdPool> vecIdReserved;
vecIdReserved.reserve(5);
for (int i = 0; i < 2; ++i) {
vecIdReserved.push_back(IdPool());
cout << "push_back to reserved vector id: " << vecIdReserved.back().id() << endl << endl;
}
return 0;
}
在测试 ID 生成器类时,我观察到以下行为:
列表:将新 ID 推送到列表中按预期工作(为临时对象提取新 ID,在临时对象被销毁后将其放回,参见输出。
向量:将新 ID 推送到向量会创建许多临时对象,对应于向量的大小。在每个 push_back 操作之后,向量在尾部包含相同的 ID,请参见下面的输出。如果我想使用 IdPool 类来识别派生类的实例,这不是所需的行为。对于列表,我希望每个 push_back 操作只有一个 temp。我在这里错过了什么?
编辑: 推送到预先分配的向量与列表一样。在这种情况下,这可能是要走的路。我只需要记住在使用矢量之前进行预订。
输出
-- push 2 IDs to list --
c'tor id: 1
copy c'tor id: 2
d'tor free id: 1
push_back to list id: 2
c'tor id: 1
copy c'tor id: 3
d'tor free id: 1
push_back to list id: 3
-- push 2 IDs to vector --
c'tor id: 1
copy c'tor id: 4
d'tor free id: 1
push_back to vector id: 4
c'tor id: 1
copy c'tor id: 5
d'tor free id: 4
copy c'tor id: 4
d'tor free id: 1
push_back to vector id: 4
-- push 2 IDs to preallocated vector --
c'tor id: 1
copy c'tor id: 6
d'tor free id: 1
push_back to reserved vector id: 6
c'tor id: 1
copy c'tor id: 7
d'tor free id: 1
push_back to reserved vector id: 7
【问题讨论】:
-
请阅读How to Ask并在您的问题中编辑minimal reproducible example。