在定位产品崩溃的问题中,出现这样一个问题
下面的例子中,子类成员中包含父类指针的容器,并且成员函数提供外部调用的接口用于销毁这个父类指针的容器,并且子类的析构函数也会调用这个成员函数,如果父类的析构是虚析构,那么delete对象的时候就会找到对应类型的子类的析构函数,对于这种情况就有可能同一个对象调用两次delete,结果将无法预料,比如就出现了崩溃
class testa
{
public:
virtual ~testa() {};
};
class testb : public testa
{
public:
~testb() { release(); };
void release() {
for (auto data : m_vecData)
{
delete data;
}
m_vecData.clear();
};
std::vector<testa*> m_vecData;
};
int main()
{
testa* pData = new(std::nothrow) testa();
testb test;
test.m_vecData.push_back(pData);
test.release();
}
这种情况就可以将成员中的对象指针使用unique_ptr
在C++中,使用 std::unique_ptr 管理内存时,不需要手动调用 delete 来释放内存。std::unique_ptr 会自动为你管理内存的生命周期。当 std::unique_ptr 的实例被销毁时(例如,当它离开作用域或者被重新赋值时),它会自动释放它所管理的对象。
class testa
{
public:
virtual ~testa() {};
};
class testb : public testa
{
public:
~testb() { release(); };
void release() {
m_vecData.clear();
};
std::vector<std::unique_ptr<testa>> m_vecData;
};
int main()
{
testa* pData = new(std::nothrow) testa();
testb test;
test.m_vecData.push_back(std::unique_ptr<testa>(pData));
test.release();
}
也可以不直接对成员变量做delete,通过交换到临时的变量中也可以防止出现这种问题
以上主要是虚析构会引发的问题