Thread: virtual destructors

  1. #1
    Performer
    Join Date
    Jan 2007
    Location
    Macedonia
    Posts
    54

    virtual destructors

    When should i make the destrucor virtual.Is it when I have virtual functions in my class.
    But if I dont make the destructor virtual it still works!

  2. #2
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by crvenkapa View Post
    When should i make the destrucor virtual.Is it when I have virtual functions in my class.
    But if I dont make the destructor virtual it still works!
    It works until you try to delete an object via a pointer to a base class instead of a pointer to the actual class itself...

  3. #3
    carry on JaWiB's Avatar
    Join Date
    Feb 2003
    Location
    Seattle, WA
    Posts
    1,972
    Your destructor should be virtual if the class will be derived from. Here's an example where the destructor of a base class is not declared virtual:
    Code:
    #include <iostream>
    
    class Base
    {
    public:
      ~Base() { std::cout<<"Base::~Base\n"; }
    private:
    };
    
    class Derived: public Base
    {
    public:
      ~Derived() { std::cout<<"Derived::~Derived\n"; }
    };
    
    int main()
    {
      {
      Derived d1;
      Base* d2 = new Derived;
      delete d2; //only base destructor called
                      //this is not the behavior we want
    
      } //derived and base destructor called for d1
    
    }
    "Think not but that I know these things; or think
    I know them not: not therefore am I short
    Of knowing what I ought."
    -John Milton, Paradise Regained (1671)

    "Work hard and it might happen."
    -XSquared

  4. #4
    Sweet
    Join Date
    Aug 2002
    Location
    Tucson, Arizona
    Posts
    1,820
    When your child class derives from a base class and you are using pointers to allocate your classes
    Code:
    #include <iostream>
    
    class CBaseClass
    {
    public:
    	CBaseClass() : mVal(10){}
    	~CBaseClass()
    	{
    		std::cout<<"Base Destructor";
    		std::cin.get();
    	};
    protected:
    	int mVal;
    };
    
    class CChildClass : public CBaseClass
    {
    public:
    	CChildClass()
    	{
    		mPtr = new int;
    	}
    	~CChildClass()
    	{
    		std::cout<<"Child Destructor";
    		delete mPtr;
    		std::cin.get();
    	}	
    private:
    	int *mPtr;
    };
    
    int main()
    {
    	CBaseClass *childClass = new CChildClass();
    
    	delete childClass;
    }
    What doesn't get called here? That is no good now we have a memory leak.

    Now the proper way:
    Code:
    #include <iostream>
    
    class CBaseClass
    {
    public:
    	CBaseClass() : mVal(10){}
    	virtual ~CBaseClass()
    	{
    		std::cout<<"Base Destructor";
    		std::cin.get();
    	};
    protected:
    	int mVal;
    };
    
    class CChildClass : public CBaseClass
    {
    public:
    	CChildClass()
    	{
    		mPtr = new int;
    	}
    	virtual ~CChildClass()
    	{
    		std::cout<<"Child Destructor";
    		delete mPtr;
    		std::cin.get();
    	}	
    private:
    	int *mPtr;
    };
    
    int main()
    {
    	CBaseClass *childClass = new CChildClass();
    
    	delete childClass;
    }
    What happens here. Looks like everything got clean up and was called.
    Woop?

  5. #5
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    >> Your destructor should be virtual if the class will be derived from.
    Publically derived from and used polymorphically. There are some cases where classes can be publically derived from but are not intended to be used polymorphically, so the virtual destructor is not necessary.

    Also, in JaWiB's example when you delete d2 (or in prog-bman's first example), the result is undefined behavior. It might actually work. It might also crash. If it does work on your machine this time, you cannot rely on that, and should therefore always make the destructor virtual if the class is intended to be a base class that is used polymorphically.

  6. #6
    Massively Single Player AverageSoftware's Avatar
    Join Date
    May 2007
    Location
    Buffalo, NY
    Posts
    141
    Probably worth noting that none of the standard library classes have virtual destructors (to the best of my knowledge) so be careful if you decide to subclass them publicly.

    Doesn't matter so much for private and protected inheritance.

  7. #7
    Registered User
    Join Date
    May 2007
    Posts
    147
    Doesn't matter so much for private and protected inheritance.
    Pardon me for interjecting on this point, but I think this isn't accurate if you mean that virtual destructors could be avoided if inheritance is private or protected.

    I think the importance is the same - could you explain?

  8. #8
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    Generally privately inherited classes are not used polymorphically, which is why it is not necessary to make the destructor virtual in those cases.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. virtual destructors
    By coletek in forum C++ Programming
    Replies: 2
    Last Post: 01-11-2009, 12:14 PM
  2. Replies: 48
    Last Post: 09-26-2008, 03:45 AM
  3. Virtual & Pure virtual destructors
    By BMJ in forum C++ Programming
    Replies: 61
    Last Post: 08-22-2002, 09:38 AM
  4. C++ XML Class
    By edwardtisdale in forum C++ Programming
    Replies: 0
    Last Post: 12-10-2001, 11:14 PM
  5. Exporting Object Hierarchies from a DLL
    By andy668 in forum C++ Programming
    Replies: 0
    Last Post: 10-20-2001, 01:26 PM