Thread: Trouble understanding virtual destructor example?

  1. #1
    Registered User
    Join Date
    Jun 2014
    Location
    Tampa, Florida, United States
    Posts
    28

    Trouble understanding virtual destructor example?

    I'm studying for my upcoming final and I can't understand this particular problem regarding virtual destructors:

    Code:
    #include <iostream>
    using namespace std; 
    
    class A
    {
       public:
    
              A(int n =2) 
                :x(n)  
              {
                   cout "A constructor " << endl; 
              }
              virtual void Add(int n)
              {
    
                 x+=n;
              }
    
              virtual ~A()
              {
    
                  cout << x << endl; 
                  cout << "A destructor " << endl; 
              }
    
              protected:
                    int x; 
    
    };
              
    Class B: public A
    {
    
        public:
               B(int n)
                  :A(n)  
               {
    
                    y= 0; 
                    z=0; 
                    cout << "B constructor" << endl; 
                }
    
               void Add(int n)
               {
    
                   x= 0; 
                   y +=n; 
                   z = 1; 
                }
    
                ~B()
                {
    
                      cout << "B destructor " << endl; 
                      std::cout << y << z; 
                 } 
                 private:
    
                     int y; 
                     int z;
    };
    
    
    int main()
    {
    
           int c =1; 
           B *b = new B(5); 
           A *a
           a = b; 
           a -> Add(c); 
           delete a; 
           std::cout << std::endl; 
           return 0; 
    }

    and the out put is:

    A constructor
    B constructor
    B destructor
    110
    A destructor

    I think I understand most of it, but there are certain things that i'm a little unsure of:

    A constructor
    B constructor

    reason: b pointer is allocated and points to derived object, meaning A constructor is called, followed by inherited B constructor


    B destructor

    reason: called because we deleted the a pointer which pointed to the derived object, so it utilizes it's derived class B destructor. The a->add(c), sends c to the derived B class add function, which sets x=0, y=1 and z =1. This makes the output 110 based on how the variables print in the B class destructor.


    here's where i'm tripping up:

    A constructor

    reason: Is this because right after the a pointer is deallocated, the base class destructor activates, and then prints that out? What about the b pointer that ISNT explicitly deleted when the main function terminates, shouldn't this also print out Another:

    B destructor
    A destructor


    for the b pointer?

    Sorry If this is fairly long.
    Last edited by garmbrust; 04-24-2015 at 06:04 PM.

  2. #2
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    When you create a derived object, you must also create its base objects. So when you create a B, you must also create its A part. Therefore, A's constructor is called first and then B's.
    When you destroy an object, the reverse must be done. First you must destroy the B part and then the A part. While B is technically an A, the A part of B and the B part of B are separate parts of the object. The B class does not know how to construct an A. A's constructor does. Similarly, class A does not know how to construct a B. B's constructor knows this. It's the same story for the destructors. Since B does not know how to destroy the A part, it calls A's destructor to finish that part. The compiler calls B's destructor and B's destructor will then call A's destructor.

    As for if you don't delete the pointer... then no destructor will be called at all. Destructors are only called when an object is destroyed. If you don't delete what you new, then it will never be destroyed (only the pointer that points to it).
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  3. #3
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    The code did not compile as written. Make sure to copy the code exactly as it is from the editor. You know what the output is, so there is no excuse for these little mistakes in the code on the board.

    You know you constructed one object, right?
    B *b = new B(5);

    The A pointer allows you to access the B part of the object polymorphically. So when you call a->Add(c); the function invoked is actually B::Add(int n). When the destructor is called, the B part is actually destroyed first, then the A part.

    That's all that happens in your code too. The output is just confusing. If we change the code slightly it might be clearer. I propose new destructors:
    Code:
              virtual ~A()
              {
                  cout << "A destructor " << endl;
                  cout << "...x: " << x << endl;  
              }
    
                ~B()
                {
    
                      cout << "B destructor " << endl; 
                      std::cout <<"...y: " << y << "...z: " << z << endl; 
                 }
    Now the output is:

    A constructor
    B constructor
    B destructor
    ...y: 1...z: 1
    A destructor
    ...x: 0

    Now that you know what members are from what objects, does it make more sense how the object is deleted now?

  4. #4
    Registered User
    Join Date
    Jun 2014
    Location
    Tampa, Florida, United States
    Posts
    28
    Quote Originally Posted by whiteflags View Post
    The code did not compile as written. Make sure to copy the code exactly as it is from the editor. You know what the output is, so there is no excuse for these little mistakes in the code on the board.

    You know you constructed one object, right?
    B *b = new B(5);

    The A pointer allows you to access the B part of the object polymorphically. So when you call a->Add(c); the function invoked is actually B::Add(int n). When the destructor is called, the B part is actually destroyed first, then the A part.

    That's all that happens in your code too. The output is just confusing. If we change the code slightly it might be clearer. I propose new destructors:
    Code:
              virtual ~A()
              {
                  cout << "A destructor " << endl;
                  cout << "...x: " << x << endl;  
              }
    
                ~B()
                {
    
                      cout << "B destructor " << endl; 
                      std::cout <<"...y: " << y << "...z: " << z << endl; 
                 }
    Now the output is:

    A constructor
    B constructor
    B destructor
    ...y: 1...z: 1
    A destructor
    ...x: 0

    Now that you know what members are from what objects, does it make more sense how the object is deleted now?

    Yes I think it's starting to make sense now. So basically you aren't just deleting the pointer, but also the object to which it points when you delete it? Meaning it deletes the B portion first, and then the a portion?


    What would happen if we were to hypothetically delete b, would that produce the same result too since it points to the same object..?

  5. #5
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    Quote Originally Posted by garmbrust View Post
    Yes I think it's starting to make sense now. So basically you aren't just deleting the pointer, but also the object to which it points when you delete it? Meaning it deletes the B portion first, and then the a portion?
    It works this way because of the virtual functions. The virtual interface is polymorphism.

    Quote Originally Posted by garmbrust View Post
    What would happen if we were to hypothetically delete b, would that produce the same result too since it points to the same object..?
    That's right, the same thing happens. The difference is that you aren't using polymorphism anymore, since you are just directly calling B's destructor.
    Last edited by whiteflags; 04-24-2015 at 07:57 PM.

  6. #6
    Registered User
    Join Date
    Jun 2014
    Location
    Tampa, Florida, United States
    Posts
    28
    Quote Originally Posted by whiteflags View Post
    It works this way because of the virtual functions. The virtual interface is polymorphism.


    That's right, the same thing happens. The difference is that you aren't using polymorphism anymore, since you are just directly calling B's destructor.

    Ahh I see. Thanks for the help guys! I feel pretty solid on the material now.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Destructor as a virtual
    By Samson144 in forum C++ Programming
    Replies: 4
    Last Post: 06-01-2011, 04:09 AM
  2. virtual destructor SYNTAX
    By rahulsk1947 in forum C++ Programming
    Replies: 6
    Last Post: 06-12-2009, 11:26 PM
  3. A virtual destructor dilema
    By tzakieta in forum C++ Programming
    Replies: 10
    Last Post: 09-11-2008, 09:22 AM
  4. virtual destructor
    By George2 in forum C++ Programming
    Replies: 12
    Last Post: 10-18-2007, 12:33 PM
  5. Virtual functions but non-virtual destructor
    By cunnus88 in forum C++ Programming
    Replies: 4
    Last Post: 03-31-2007, 11:08 AM