我有一个程序,其中包含一个处理阶段,需要使用来自一个多态类型树的不同对象实例(全部在堆上分配),最终都派生自一个共同的基类。
由于这些实例可能循环地相互引用,并且没有明确的所有者,因此我想用 new
分配它们,用原始指针处理它们,并将它们保留在内存中以供该阶段使用(即使它们变得无引用),然后在使用这些实例的程序阶段之后,我想一次性将它们全部删除。
我考虑的结构如下:
struct B; // common base class
vector<unique_ptr<B>> memory_pool;
struct B
{
B() { memory_pool.emplace_back(this); }
virtual ~B() {}
};
struct D : B { ... }
int main()
{
...
// phase begins
D* p = new D(...);
...
// phase ends
memory_pool.clear();
// all B instances are deleted, and pointers invalidated
...
}
除了小心确保所有的B实例都是通过new分配的,并且在内存池清空后没有人再使用指向它们的指针,这个实现有什么问题吗?
具体而言,我担心基类构造函数中使用this
指针来构造一个std::unique_ptr
,而此时派生类构造函数还没有完成。这会导致未定义行为吗?如果是,是否有解决方法?
B
需要了解内存池?从驱动程序代码(main
)添加指针似乎是更好的选择。当然,内存池的生命周期可以被限制,这意味着当其超出范围时会自动释放。 - Jonmemory_pool.emplace_back(new D(...))
替换对new D(...)
的调用吗?我想我可以编写一个模板函数,类似于make_shared
的风格来构造对象,将参数转发给构造函数,并将其添加到内存池中。不过,我仍然想知道上面的代码是否存在未定义行为。 - Andrew Tomazos