Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any automated way to implement post-constructor and pre-destructor virtual method calls?

Due to the well-known issues with calling virtual methods from inside constructors and destructors, I commonly end up with classes that need a final-setup method to be called just after their constructor, and a pre-teardown method to be called just before their destructor, like this:

MyObject * obj = new MyObject;
obj->Initialize();   // virtual method call, required after ctor for (obj) to run properly
[...]
obj->AboutToDelete();  // virtual method call, required before dtor for (obj) to clean up properly
delete obj;

This works, but it carries with it the risk that the caller will forget to call either or both of those methods at the appropriate times.

So the question is: Is there any way in C++ to get those methods to be called automatically, so the caller doesn't have to remember to do call them? (I'm guessing there isn't, but I thought I'd ask anyway just in case there is some clever way to do it)

like image 292
Jeremy Friesner Avatar asked Jul 20 '09 05:07

Jeremy Friesner


People also ask

Is it possible to call a virtual function from a constructor?

You can call a virtual function in a constructor. The Objects are constructed from the base up, “base before derived”.

Why should calls to virtual functions be avoided in constructors and destructors?

As a general rule, you should never call virtual functions in constructors or destructors. If you do, those calls will never go to a more derived class than the currently executing constructor or destructor. In other words, during construction and destruction, virtual functions aren't virtual.

Why is it not acceptable to call a virtual method from the constructor of an abstract class?

Calling virtual functions in constructors makes your code extremely sensitive to the implementation details in derived classes. You can't control what derived classes do. Code that calls virtual functions in constructors is very brittle.

Can you call virtual function in destructor?

}; Similarly, it is permissible to call a virtual function from a constructor or destructor of a class that has the final class-virt-specifier, as in this example.


2 Answers

While there is no automated way, you could force the users hand by denying users access to the destructor on that type and declaring a special delete method. In this method you could do the virtual calls you'd like. Creation can take a similar approach which a static factory method.

class MyObject {
  ...
public:
  static MyObject* Create() { 
    MyObject* pObject = new MyObject();
    pObject->Initialize();
    return pObject;
  }
  Delete() {
    this->AboutToDelete();
    delete this;
  }
private:
  MyObject() { ... }
  virtual ~MyObject() { ... }
};

Now it is not possible to call "delete obj;" unless the call site has access to MyObject private members.

like image 82
JaredPar Avatar answered Oct 15 '22 22:10

JaredPar


The best I can think of is for you to implement your own smart pointer with a static Create method that news up an instance and calls Initialize, and in its destructor calls AboutToDelete and then delete.

like image 37
Kim Gräsman Avatar answered Oct 15 '22 23:10

Kim Gräsman