Thread: Virtual & Pure virtual destructors

  1. #1
    Banal internet user
    Join Date
    Aug 2002
    Posts
    1,380

    Virtual & Pure virtual destructors

    I am a little confused about virtual and pure virtual destructors. Why and when they are used? Can I get a good explanation for needing them? (I hope that's not too much to ask )

    Anyway, all I know is that the following code will crash; can someone explain why? And why do I need to use virtual destructors to correct it?
    Code:
    class A
    {
    public:
    	~A() {}
    	int a;
    };
    
    class B
    {
    public:
    	~B() {}
    	int b;
    };
    
    class C : public A, public B
    {
    };
    
    int main()
    {
    	A* ap = new C;
    	delete ap;
    	B* bp = new C;
    	delete bp;
    
    	return 0;
    }
    And if you can, I'm just curious about what a 'pure virtual destructor' is

    Meh?

  2. #2
    Magically delicious LuckY's Avatar
    Join Date
    Oct 2001
    Posts
    856
    I don't know why you said the code crashes (do you mean it won't compile or you get a runtime explosion?), it compiled/ran okay for me.

    A pure virtual function (it can be any function, doesn't have to be the destructor) is a function that declares that you can not instantiate an object of that type. In other words, you declare a pure virtual function in a class that is strictly intended to be inherited and not used itself. The way you make a function pure virtual is to make it virtual and after the declaration add "= 0" In addition, if you inherit from such a base class, you are required to override the pure virtual function. BTW, this is what's referred to as an 'abstract base class'
    For example:
    Code:
    class BaseShape {
    public:
      virtual int GetArea() = 0;//this function is pure virtual
    };
    
    class Square : public BaseShape {
    public:
      virtual int GetArea() { return 100; }//function must be defined
    };
    
    class Triangle : public BaseShape {
    public:
      virtual int GetArea() { return 100; }//function must be defined
    };
    
    int main() {
      //BaseShape bs;//this line won't compile. can't instantiate it!
      Square *sq = new Square;
      delete sq;
    
      return 0;
    }
    The reason you should make destructors virtual when they are being inherited from is that if you don't, destructors might not be called (depending on usage).
    For example:
    Code:
    class A {
    public:
      virtual ~A() { cout << "A\n"; }
    };
    
    class B {
    public:
      ~B() { cout << "B\n"; }
    };
    
    int main() {
      A *pA = new B;
      delete pA;
      
      return 0;
    If class A's destructor wasn't virtual, ~B() would not be called upon destruction.

    HTH
    Last edited by LuckY; 08-21-2002 at 12:04 PM.

  3. #3
    Banned Troll_King's Avatar
    Join Date
    Oct 2001
    Posts
    1,784
    Maybe you need to declare the base clase destructor virtual only when you use polymorphism.

  4. #4
    Banal internet user
    Join Date
    Aug 2002
    Posts
    1,380
    I know what virtual functions are and I know what pure virtual functions are. I know that you need to use virtual destructors on base classes because of an issue with destructors not being called on derived classes; but I'm looking for a bit of a technical explination why

    And, as for the code I posted, I get an assertion error at runtime

  5. #5
    Banned Troll_King's Avatar
    Join Date
    Oct 2001
    Posts
    1,784
    Didn't you answer your own question? Use a virtual destructor in the base class when you create a derived class through a pointer to the base class. That way when the object is destroyed it will call both destructors. You need more than that?

  6. #6
    pronounced 'fib' FillYourBrain's Avatar
    Join Date
    Aug 2002
    Posts
    2,297
    Originally posted by BMJ
    I know what virtual functions are and I know what pure virtual functions are. I know that you need to use virtual destructors on base classes because of an issue with destructors not being called on derived classes; but I'm looking for a bit of a technical explination why

    And, as for the code I posted, I get an assertion error at runtime
    I should mention that I tested this in VC++ 6 and I got results different from what I expected. base class and derived class destructors got called if the base class destructor was virtual or not. I can't explain that except that VC++ 6 is supposedly not entirely standard compliant. (troll_king, this is not your cue to trash MS)
    "You are stupid! You are stupid! Oh, and don't forget, you are STUPID!" - Dexter

  7. #7
    Banned Troll_King's Avatar
    Join Date
    Oct 2001
    Posts
    1,784
    As far as I know, everything compiles with MSVC++, because it's a "Rapid Application Development" suite.

  8. #8
    Banal internet user
    Join Date
    Aug 2002
    Posts
    1,380
    In this code, why does ~B() not get called if ~A() is not virtual? Sorry if I sound like a fool but this is confusing me!
    Code:
    #include <iostream>
    
    class A
    {
    public:
    	~A() { std::cout << "~A()"; }
    };
    
    class B : public A
    {
    public:
    	~B() { std::cout << "~B()"; }
    };
    
    int main()
    {
    	A* ap = new B;
    	delete ap;
    
    	return 0;
    }
    Will output "~A()"... now I know that since ap is a pointer to type A, when it's deleted ~A() is called; Why must it be virtual to call ~B()?

  9. #9
    Banned Troll_King's Avatar
    Join Date
    Oct 2001
    Posts
    1,784
    Dude, I don't know but keep teaching us. As far as I can see you are asking a question and then answering it. That's exactly how virtual destructors work.

  10. #10
    Magically delicious LuckY's Avatar
    Join Date
    Oct 2001
    Posts
    856
    You're a funny guy BMJ. First you say:
    Originally posted by BMJ
    I'm just curious about what a 'pure virtual destructor' is
    and then you say:
    Originally posted by BMJ
    I know what pure virtual functions are
    Okay, a technical explanation using the class A, class B : public A examples. When you instantiate a 'class A' pointer with an object of type 'class B', the object you are actually handling is a pointer to an A. You cannot use any B members (without casting) because A only knows about it's own members. When destruction time comes, its going to look at its own destructor and it will see that it is not virtual, therefore it will not look for any derived destructors that need to be called, and alas, the destructor will be left out of the loop. If you want more detail on how C++ actually does that, you will have to ask Bjarne Stroustrup.

    Does that clear anything up?

    *LuckY*

  11. #11
    Banned Troll_King's Avatar
    Join Date
    Oct 2001
    Posts
    1,784
    The object is shared. Does that make sense?

  12. #12
    Banal internet user
    Join Date
    Aug 2002
    Posts
    1,380
    *thinks about it* Hmmph... I just don't like using something 'just because', I like to know what is really going on; I suppose this will suffice

    Oh, and about the pure virtual function/destructor thing... I was just curious if pure virtual destructors have any special use

  13. #13
    Banal internet user
    Join Date
    Aug 2002
    Posts
    1,380
    Thanks for your time!

  14. #14
    pronounced 'fib' FillYourBrain's Avatar
    Join Date
    Aug 2002
    Posts
    2,297
    ok, disregard my VC++ test. It's correct.

    A *a = new B;

    delete a;

    this is where you get those results. The destructor for B does not get called if A's destructor is not virtual. This actually makes perfect sense and VC++ does it correctly.

    I suppose a pure virtual destructor would be if you don't have anything to implement in your base destructor and you still need to be virtual. Plus this gives you an abstract base class
    "You are stupid! You are stupid! Oh, and don't forget, you are STUPID!" - Dexter

  15. #15
    Banned Troll_King's Avatar
    Join Date
    Oct 2001
    Posts
    1,784
    Virtual makes it so that the object is shared. You must destory all the parts of a shared object.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 3
    Last Post: 10-28-2009, 09:25 AM
  2. Replies: 48
    Last Post: 09-26-2008, 03:45 AM
  3. Information Regarding Pure Virtual Functions
    By shiv_tech_quest in forum C++ Programming
    Replies: 6
    Last Post: 01-29-2003, 04:43 AM
  4. C++ XML Class
    By edwardtisdale in forum C++ Programming
    Replies: 0
    Last Post: 12-10-2001, 11:14 PM
  5. virtual or pure virtual
    By Unregistered in forum C++ Programming
    Replies: 1
    Last Post: 12-01-2001, 07:19 PM