这是一个基于真正问题的构建方案。如果我有一个基类:删除派生对象时的行为
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;
};
然后说我有一个要求车辆:: run()的定期线程。我有另一个线程,最终删除指向汽车的指针。销毁顺序将导致车辆首先被删除,然后车辆被删除。
如果线程(生活在Vehicle对象中)调用析构函数在汽车中运行后(但显然在车辆被破坏之前)调用incrementStuff函数会发生什么? Car :: incrementStuff是否会被执行并尝试解引用已经被删除的指针?或者将调用Vehicle :: incrementStuff,这是安全的,什么都不做?
假设当Car ::〜Car()正在运行时,线程无法调用Car :: incrementStuff(这是由互斥锁阻止的)。
此代码已被重构,以避免这种情况,但我只是想知道是否有人可以阐明这是如何工作的,或者如果它只是普通的未定义行为?
更一般地说,如果我在Car被破坏之后但在Vehicle之前尝试致电Car :: incrementStuff,会发生什么? NULL检查是否工作,或者内存已经释放,现在可以被任何东西使用?或者,在基础对象被破坏之前,内存是不是“释放”的?