Am I allowed to indirectly destroy object from within object’s own virtual method?
Is it a “defined behavior” (as long as I’m not trying to access anything after destroying the object)?
Example:
#include <memory>
#include <stdio.h>
using std::tr1::shared_ptr;
struct Child{
virtual void selfdestruct() = 0;
virtual ~Child(){
fprintf(stderr, "child destroyed\n");
}
};
typedef shared_ptr<Child> ChildPtr;
struct Parent{
ChildPtr child;
void clear(){
fprintf(stderr, "clear\n");
child = ChildPtr();
}
Parent();
};
struct DerivedChild: public Child{
Parent* parent;
virtual void selfdestruct(){
fprintf(stderr, "selfdestruct\n");
if (parent)
parent->clear();
}
DerivedChild(Parent* p)
:parent(p){
}
};
Parent::Parent(){
child = ChildPtr(new DerivedChild(this));
}
int main(int argc, char** argv){
Parent p;
p.child->selfdestruct();
fprintf(stderr, "child is 0x%08x\n", p.child);
return 0;
}
Output:
selfdestruct
clear
child destroyed
child is 0x00000000
If this is not a defined behavior, what can I do instead?
Well, a virtual method can call
delete this. After the call though, NOTHING ELSE THAT TOUCHES THAT OBJECT INSTANCE can be done, or you have invoked undefined behavior. That includes calling other methods (even non virtual methods), accessing any instance variable, or the like.Your specific code above invokes undefined behavior because the
Childobject needs a virtual destructor.However, any type of situation where an object needs to destroy itself is not the best of designs.