我希望我的类拥有一个指向动态分配内存区域的静态指针。我知道如何初始化它 - 在我的情况下,当第一个对象需要它时,我会初始化它。然而,我不知道在什么时候/什么地方释放它。我希望程序终止时可以释放它。
也许我可以在我的对象析构函数中释放指针,但是那样的话我就必须维护一个对象计数器来确定在对象是最后一个正在使用的对象时是否安全释放。
有没有更优雅的方式来做这个?
请告诉我。
谢谢, jbu
我希望我的类拥有一个指向动态分配内存区域的静态指针。我知道如何初始化它 - 在我的情况下,当第一个对象需要它时,我会初始化它。然而,我不知道在什么时候/什么地方释放它。我希望程序终止时可以释放它。
也许我可以在我的对象析构函数中释放指针,但是那样的话我就必须维护一个对象计数器来确定在对象是最后一个正在使用的对象时是否安全释放。
有没有更优雅的方式来做这个?
请告诉我。
谢谢, jbu
我建议你选择第二种方法,这是一种非常干净的方法。
下面是一个简单的示例。不要这样做:
static Thing* things = new Thing(); // or whatever way to initialize, here or in a specific function
您将会这样做:
class ThingManager // or whatever name you like
{
public:
ThingManager( Thing* thing ) : m_thing( thing ) { }//or create it here? whatever solution suits your way of creating the data
~ThingManager() { delete m_thing; } // THAT's the important part!
Thing* instance() const { return m_thing; } // or whatever accessor you need, if you need one
private:
Thing* m_thing;
};
然后
static ManagedThing thing; // now i can access it via thing.instance()
当程序结束时,静态变量(不再是指针)将被销毁,并将调用它的析构函数进行清理。
这只是为了让您了解如何做到这一点。
将它放入智能指针中。它将具有静态生命周期,并在main
返回后被销毁:
static std::auto_ptr<T> thePointer;
atexit
函数:// static
void YourClass::freePointer(void)
{
delete getPointer();
}
// static
T* YourClass::getPointer(void)
{
if (!thePointer)
{
thePointer = new T;
atexit(freePointer);
}
return thePointer;
}
这会产生相同的效果。你已经提到的另一个选项是保持静态计数器。请注意,你实际上可以将其有效地封装起来。
Loki::Singleton
实现中使用了atexit
。这样,他确保释放指针的方法也将其状态重置为0
,以便在需要时可以重新分配(例如Phoenix
生命周期策略的情况)。个人认为,使用auto_ptr
或者更好的unique_ptr
会更加方便。 - Matthieu M.free
只是在堆中移动指针,而这些指针最终都会被抛弃。malloc
和 free
将分配块添加/删除到分配列表中。每个分配需要 8 个字节和一次中断开/关循环的成本,但允许操作系统在进程终止时释放它们。每个进程的堆可以实现相同的功能(我认为该系统没有使用堆的原因是因为它们使释放空闲内存以供其他进程使用变得更加困难,而这对该系统是可取的)。 - Steve Jessop您可以将静态变量声明为智能指针,这样当程序结束时,分配的指针将被释放。
当我试图在退出时释放自己的静态指针时,我偶然发现了这篇旧文章。
正确的C++(C++11)解决方案是使用智能指针,可以使用std::unique_ptr<T>
或std::shared_ptr<T>
,其中T是您正在初始化的对象类型。这些模板管理对象的生命周期,并在作用域结束时或成为内存中最后一个引用时删除对象。