CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 7 of 7
  1. #1
    Join Date
    Jun 2010
    Posts
    115

    Question virtual destructor

    What if I don't declared virtual for my destructor ?

    class Base
    {
    public: virtual void func()=0;
    };

    class Derivedublic Base
    {
    public:void func(){//dosomething}
    };
    ????
    Thank you.

  2. #2
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: virtual destructor

    Quote Originally Posted by Maejie
    What if I don't declared virtual for my destructor ?
    Then if you ever use delete or delete[] on a Base pointer that points to a Derived object, you get undefined behaviour.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  3. #3
    Join Date
    May 2007
    Location
    Scotland
    Posts
    1,164

    Re: virtual destructor

    In addition to what laserlight has written, any class you derive from should have a public virtual destructor (implicit from further base classes or explicitly marked as such):

    e.g.

    Code:
    struct Base
    {
      virtual ~Base(){} 
    };
    
    struct Middle : Base {};
    
    struct Derived : Middle {};
    
    int main()
    {
      Base b* = new Derived();
    
      delete b; //OK, nothing will be leaked because Base is explicitly
                //marked virtual
    
    
      Middle m* = new Derived();
    
      delete m; //OK, nothing will be leaked because the destructor 
                //of Middle is implicitly virtual because Middle derives 
                //from Base, and Base has a virtual destructor
    
    
      Derived d* = new Derived();
    
      delete d //OK, nothing will be leaked, deleted from derived pointer.
    }
    or a protected destructor

    Code:
    struct Base
    {
    protected:
      ~Base(){}
    };
    
    struct Derived {};
    
    int main()
    {
      Base b* = new Derived();
    
      delete b; //Compile error, Derived must be deleted from a derived 
                //pointer (should dynamic cast the base pointer to the 
                //derived pointer and then delete via the derived pointer.
    
      Derived d* = new Derived();
    
      delete d; //OK, nothing will be leaked, deleted from derived pointer.
    }
    If you use protected inheritance you should be very careful if the protected destructor is not marked virtual... consider what happens in the following code...

    Code:
    struct Base
    {
    protected:
      ~Base(){}
    };
    
    struct Middle : Base {};
    
    struct Derived {};
    
    int main()
    {
      Base b* = new Derived();
    
      delete b; //Compile error, Derived must be deleted from a derived 
                //pointer (should dynamic cast the base pointer to the 
                //derived pointer and then delete via the derived  pointer.
    
    
      Derived d* = new Derived();
    
      delete d //OK, nothing will be leaked, deleted from derived pointer.
    
    
      Middle  m* = new Derived();
    
      delete m; //No compile error but the Derived section of the
                //allocation will not be deleted.
    }
    If you cannot modify the Base class, the problem in the above code can be solved by making the destructor of Middle virtual:

    Code:
    struct Middle : Base
    {
      virtual ~Middle(){}
    };
    Anyway, I would advise using public inheritance.
    Last edited by PredicateNormative; August 16th, 2011 at 05:33 AM. Reason: grammar

  4. #4
    Join Date
    Jun 2010
    Posts
    115

    Re: virtual destructor

    Thank you soooooo very much for your helpful reply
    But in the third code block,
    Code:
     delete m; //No compile error but the Derived section of the
                 //allocation will no be deleted
    How could you know that ?

  5. #5
    Join Date
    Apr 1999
    Posts
    27,449

    Re: virtual destructor

    Quote Originally Posted by Maejie View Post
    Thank you soooooo very much for your helpful reply
    But in the third code block,
    Code:
     delete m; //No compile error but the Derived section of the
                 //allocation will no be deleted
    How could you know that ?
    Let's give you an easy example:
    Code:
    class Base
    {
        public:
           char *p;
            Base() { p = new char [10]; }
           ~Base() { delete [] p; }
    };
    
    class Derived : public Base
    {
        public:
           char *ptr;
           Derived() { ptr = new char [10]; }
         ~Derived() { delete [] ptr; }
    }
    
    int main()
    {
        Base *pb = new Derived;
        delete pb;   // behaviour is undefined
    }
    If you are deleting a derived object through a base class pointer, and the base class does not have a virtual destructor, the behaviour is undefined.

    The above code may result in a memory leak, maybe not -- that's what is meant by undefined behaviour. To ensure that both derived and parent are destroyed, the base class's destructor must be virtual.

    Edit: Changed name of derived pointer.

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; August 15th, 2011 at 03:36 PM.

  6. #6
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: virtual destructor

    It may be less confusing if Derived had a pointer of a different name than Base as a member.

  7. #7
    Join Date
    Jun 2010
    Posts
    115

    Re: virtual destructor

    Thank you Paul and Lindley, I understand virtual destructor better now.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured