存储对象池的两种数据结构(区别)
探讨一下,我要为基类A创建一个对象池,有两种方案(假设对象池大小为1024):
方法一(数组):
class AMnger{
...
void init()
{
_obj = new A[1024];
}
private:
A *_obj;
};
方法二(指针数组):
class AMnger{
...
void init()
{
_obj = new A*[1024];
for (int i = 0; i < 1024; ++i)
{
_obj[i] = new A;
}
}
private:
A **_obj;
};
这两个方法在我现在项目中都有用到,我想讨论下它们的区别。我觉得它们的实际效果是一样的,如果要得到某个对象的指针,无非是&_obj[i]和_obj[i]的区别。
除此之外,我觉得还有一点区别,方法一要求一下子开辟一段连续的内存,如果A比较大,系统资源吃紧时可能失败;方法二则把这种连续内存分散来开辟,要优一些。
各位觉得呢?
[解决办法]
指针数组存放基类指针可以实现多态,对象数组就不行了,只能放同样大小的。
连续内存的对象数组也有好处,可以一下子new一块大的内存,每个对象用placement new分配,对象复用的效率高(不用反复delete和new内存)。
[解决办法]
我觉得一更好,第二种方法,
(1) 容易产生碎片
(2) 容易 cache miss 降低效率,因为对象散布在各处。
(3) 如果 for 中某个 new 失败的话,还得处理收摊的问题。方法一要么都有,要么都没有,不存在半不勒勒的事儿。
[解决办法]
对象越小, 浪费的空间越多.