是的,您可以相信向量会在完成任务后自我清理。
然而,您不能相信向量所持有的内容能够自我清理。需要清理的可能是应用程序之外的持久化数据。如果需要清理的是内存,则不必担心。但如果需要确保 XML 标记都已关闭,则操作系统将无法帮助您。
例如,如果您有一个包含一些奇怪锁定对象的向量,如下所示:
class CLock
{
public:
CLock() {}
~CLock() {}
void Lock(...) {...}
void Unlock(...) {...}
};
std::vector<CLock> myLockVec;
当向量完成时,您的 CLock 向量如何知道解锁所有内容?向量不具备了解锁的能力。
这与拥有指针向量的情况基本相同:
std::vector<int*> myIntVec
向量如何知道哪些指针已被删除和设置为NULL,哪些仍然存在?也许有些已经被删除并设置为您的特殊值0xdeadbeef,表示已删除。
重点是向量没有办法知道这一点,也不知道它的元素是指针、锁或其他什么。它们只需要是具有默认构造函数、可复制并满足向量对其元素的其他要求的东西。
解决方案是确保无论向量持有什么都需要负责清理。这被称为RAII——资源分配即初始化,更重要的是,在这里,资源销毁就是释放。对于上面的我们的CLock示例,答案很明显,确保在完成后解锁!
class CLock
{
...
~Clock()
{
if (locked)
{
Unlock();
}
}
}
但是指针并不那么显而易见。解决方法是将指针包装在smart_ptr类中。其中最常用的就是boost智能指针家族。
class CSmartPointer<T>
{
CSmartPointer( T* rawPtr)
{
m_ptr = rawPtr;
}
~CSmartPointer()
{
delete m_ptr;
}
}
指针等功能带来了额外的特性,例如引用计数,但上面的示例应该能让您了解问题的本质及其通常解决方法。