C++ 删除派生对象时的行为
这是一个基于真实问题的虚构场景。如果我有一个基类:C++ 删除派生对象时的行为,c++,inheritance,destructor,C++,Inheritance,Destructor,这是一个基于真实问题的虚构场景。如果我有一个基类: class Vehicle { public: void run() { incrementStuff(); } virtual void incrementStuff() { } }; 和派生类: class Car : public Vehicle { public: Car() : Vehicle() { stuff = new StuffClass(); } ~Car() { delete
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()。我有另一个线程,它最终会删除指向car的指针。销毁顺序将导致先删除car,然后删除车辆
如果线程(位于Vehicle对象中)在析构函数在汽车中运行后调用incrementStuff函数(但显然是在汽车被破坏之前),会发生什么情况?是否将执行Car::incrementStuff并尝试取消引用已删除的指针?或者调用Vehicle::incrementStuff,它是安全的,并且什么也不做
假设在Car::~Car()运行时线程无法调用Car::incrementStuff(这是由互斥锁阻止的)
为了避免这种情况,我对代码进行了重构,但我只是想知道是否有人能够解释这是如何工作的,或者这仅仅是一种未定义的行为
更一般地说,若我在汽车被破坏之后但在汽车被破坏之前尝试调用Car::incrementStuff会发生什么?空检查是否有效,或者该内存是否已经释放,现在可以被任何东西使用?或者,在基本对象被破坏之前,内存不会被“释放”吗?您考虑得太多了。如果取消引用已被
delete
ed删除的指针,则调用未定义的行为。这就是你真正需要知道的。只要您呼叫删除ptr代码>ptr
无效
同步对此对象的访问。如果您已删除Car
对象,则对incrementStuff()
的后续调用是未定义的行为
另外,您可能应该在车辆
类虚拟
中设置析构函数。请参阅:一个线程正在读取一个值,而另一个线程正在写入该值。这是一场数据竞赛。如果两个动作没有正确同步,则行为未定义