这是一个基于真实问题的虚构场景。如果我有一个基类:
class Vehicle
{
public:
void run() { incrementStuff(); }
virtual void incrementStuff() { }
};
和一个派生类:
class Car : public Vehicle
{
public:
Car() : Vehicle() { stuff = new StuffClass(); }
~Car() { delete stuff; stuff = NULL; }
virtual void incrementStuff() { if (stuff != NULL) stuff->increment(); }
protected:
StuffClass* stuff;
};
然后说我有一个线程定期调用 Vehicle::run() 。我有另一个线程最终删除了指向汽车的指针。销毁顺序将导致汽车先被删除,然后是车辆。
如果线程(位于 Vehicle 对象中)在析构函数在 car 中运行之后(但显然在车辆被破坏之前)调用 incrementStuff 函数会发生什么?是否会执行 Car::incrementStuff 并尝试取消引用已删除的指针?还是会调用 Vehicle::incrementStuff ,它是安全的并且什么都不做?
假设当 Car::~Car() 正在运行时线程不能调用 Car::incrementStuff(这是由互斥锁阻止的)。
这段代码已被重构以避免这种情况,但我只是想知道是否有人可以阐明它是如何工作的,或者它是否只是简单的未定义行为?
更一般地说,如果我在 Car 被销毁但在 Vehicle 被销毁之前尝试调用 Car::incrementStuff 会发生什么?NULL 检查会起作用,还是该内存已经被释放并且现在可以被任何东西使用?或者,在基础对象被破坏之前,该内存不会“释放”?