c ++垃圾收集和调用析构函数

ddi*_*git 2 c++ garbage-collection

每帧我需要分配一些需要坚持到框架结束的数据.

目前,我正在从不同的内存池中分配数据,这允许我用帧计数标记它.在帧结束时,我遍历内存池并删除在特定帧中分配的内存.

我遇到的问题是,为了保持数据,我必须将它放在一个结构中:

struct FrameMemory
{
    uint32 frameIndex;
    bool allocatedType; //0 = new(), 1 = new[]
    void* pMemPtr;
}
Run Code Online (Sandbox Code Playgroud)

所以后来,当我开始释放内存时,它看起来像这样:

{
for(all blocks)
 if(block[i].frameIndex == targetIndex)
     if(block[i].allocatedType == 0)
          delete block[i].pMemPtr;
     else if (block[i].allocatedType ==1)
          delete[] block[i].pMemPtr;
}
Run Code Online (Sandbox Code Playgroud)

问题在于,因为我必须将指向内存的指针重载为void*,所以DELETE运算符不能正确地将内存作为其"本机基类型"删除.IE析构函数NEVER为对象调用.

我试图找到使用智能指针模板化对象的方法,但为了做到这一点,我必须将模板化的类重载为非模板化的基类型,这使得删除更加困难.

有没有人能解决这样的问题?

moo*_*dow 6

class Destructable
{
public:
   virtual ~Destructable() {}
};
Run Code Online (Sandbox Code Playgroud)

而不是void*,将Destructable*存储在池中.使从池中分配的对象继承自Destructable.

或者,覆盖运算符newdelete相关类.让他们使用游泳池.CPU完成后,以常规方式,在拥有它的代码中删除对象,因此知道它的正确类型; 因为池在它看到适当的帧结束之前不会重用内存,所以你需要以这种方式延迟垃圾收集的异步硬件仍然可以做到这一点.

  • 然后你将不得不创建一个包装器.或者为该类型使用单独的池.池本身可以是一个类模板,包含您需要的任何类型的对象.C++是一种静态类型语言.试图强迫它表现得像动态类型语言是一个坏主意.我知道,因为我已经尝试过了.:) (3认同)

Jer*_*fin 6

如果您不想强制所有对象继承Destructible,您可以存储指向删除函数(或函子)的指针以及指向数据本身的指针.客户端代码负责提供一个知道如何正确删除数据的函数,通常类似于:

void xxx_deleter(void *data) { 
    xxx *ptr = static_cast<xxx *>(data);
    delete ptr;
}
Run Code Online (Sandbox Code Playgroud)

尽管删除器通常与上面的很相似,但这也使客户端可以选择存储复杂的数据结构并仍然可以正确删除它们.