   [C++] Purely virtual destructor madness
  I found this the hard waystruct Interface {static Interface * create () ;virtual ~Interface (){}void virtual do_something () = 0 ;} ;struct Implementation : public Interface {int data ;virtual ~Implementation () ;void do_something () ;} ;main (){Interface * p = Interface::create () ;/*Will NOT work. ~Implementation() will not be called*/delete p ;}struct Interface {static Interface * create () ;virtual ~Interface () = 0 ;void virtual do_something () = 0 ;} ;Interface ::~Interface (){}class Implementation : public Interface {int data ;virtual ~Implementation () ;void do_something () ;} ;main (){Interface * p = Interface::create () ;/*This will work. ~Implementation() will be called.*/delete p ;}My question is why the first example does not work?   
  Your first example does work for me (once I implement the missing functions)struct Interface {static Interface* create();virtual ~Interface() { printf("~Interface"); }void virtual do_something() = 0 ;};struct Implementation : public Interface {int data ;virtual ~Implementation() { printf("~Implementation"); }void do_something() {}};Interface * Interface::create () { return new Implementation; }int main(){Interface * p = Interface::create();delete p;return 0;}When I run this, it prints "~Implementation" and then prints "~Interface", as expected.What does your Interface::create function look like?   ;  It may be a hack but I always make a Delete function:class CWhatever{public:    virtual void Delete() { delete this; };};and call it instead of using the delete keyword. It's a bit of a hack but I haven't ever had any problems and I rest easy knowing my destructors are being called properly.   ;Quote:Original post by BSVinoIt may be a hack but I always make a Delete function:*** Source Snippet Removed ***and call it instead of using the delete keyword. It's a bit of a hack but I haven't ever had any problems and I rest easy knowing my destructors are being called properly.You do realize that you'd still need a virtual destructor on a polymorphic type, right?  In which case such a delete function is unnecessary since the delete keyword will handle everything for you.  As a matter of fact, this delete function "idiom" might be dangerous if you accidentally use it in lieu of a virtual destructor...   ;  Actually I started doing that specifically because I was dealing with some polymorphic types and for some reason that I never figured out the proper destructor wasn't being called, so I made a Destructor() function for each class, had my Delete() call it, and used it instead of the regular destructor. It worked and my memory leaks went away, I still don't know why the actual destructor was never called.   ;  Maybe you didnt at least have a dummy virtual destructor on your base class(es). Something like this is good enough: virtual ~classname() {};;Quote:Original post by BSVinoActually I started doing that specifically because I was dealing with some polymorphic types and for some reason that I never figured out the proper destructor wasn't being called, so I made a Destructor() function for each class, had my Delete() call it, and used it instead of the regular destructor. It worked and my memory leaks went away, I still don't know why the actual destructor was never called.Non-polymorphic base class doesn't have a v-table. Compilers will jury rig vtable when such class is extended (IIRC, even if pure virtual functions are present or some such).To force such class to be polymorphic even as base, a virtual destructor is recommended for all classes which are meant to be extended.   ;Quote:Original post by HodgmanYour first example does work for me (once I implement the missing functions)*** Source Snippet Removed ***When I run this, it prints "~Implementation" and then prints "~Interface", as expected.What does your Interface::create function look like?It does exactly what you did, just `new Implementation`. But it doesn't seem to work on my Visual C++ 2008 Express.   ;Quote:Original post by hiigaraQuote:Original post by HodgmanYour first example does work for me (once I implement the missing functions)*** Source Snippet Removed ***When I run this, it prints "~Implementation" and then prints "~Interface", as expected.What does your Interface::create function look like?It does exactly what you did, just `new Implementation`. But it doesn't seem to work on my Visual C++ 2008 Express.I compliled the code that I posted on MSVC 2008 express and it worked... You can give that minimal code a go for yourself and see that it should work.I'm guessing that you've got some kind of memory corruption bug elsewhere in your code that's causing this "pure virtual destructor" problem to appear.;Quote:Original post by HodgmanQuote:Original post by hiigaraQuote:Original post by HodgmanYour first example does work for me (once I implement the missing functions)*** Source Snippet Removed ***When I run this, it prints "~Implementation" and then prints "~Interface", as expected.What does your Interface::create function look like?It does exactly what you did, just `new Implementation`. But it doesn't seem to work on my Visual C++ 2008 Express.I compliled the code that I posted on MSVC 2008 express and it worked... You can give that minimal code a go for yourself and see that it should work.I'm guessing that you've got some kind of memory corruption bug elsewhere in your code that's causing this "pure virtual destructor" problem to appear.You are right. It was something else. I was doing something evil with a smart pointer that I omitted when I posted the code because I thought it would be irrelevant. I removed the smart pointer at the same time I removed the inline destructor.template <typename T>class Smartpointer {public:  explicit Smartpointer ( T * inPtr ) ;  ~Smartpointer();  Smartpointer(const Smartpointer<T>& src);  Smartpointer<T>& operator=(const Smartpointer<T>& rhs);  const T& operator*() const;  const T* operator->() const;  T& operator*();  T* operator->();  operator void*() const { return mPtr; } protected:  T* mPtr;  static map<T*, int> sRefCountMap;  void finalizePointer();  void initPointer(T* inPtr);} ;main (){Smartpointer<Interface> Smartp ( Interface::create () ) ;delete Smartp ;}delete Smartp is actually deleting a void * not an Interface *.I know. Don't ask me what a hell I was thinking when I wrote this code. 