Thread: Explicitly calling destructor.

  1. #1
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544

    Explicitly calling destructor.

    The documentation says:
    You are responsible for deleting the GDI bitmap and the GDI palette. However, you should not delete the GDI bitmap or the GDI palette until after the GDI+ Bitmap object is deleted or goes out of scope.
    My code says:
    Code:
    Bitmap bmpPdf(hBitmap, NULL);
    
         ....
    
    bmpPdf.~Bitmap();
    DeleteObject(hBitmap);
    I'm wondering:
    - Is calling the destructor explicitly the equivalent of the object going out of scope?
    - Is this acceptable practise?
    - Is this common as I haven't seen it before?

    Thanks.

  2. #2
    Programming Sex-God Polymorphic OOP's Avatar
    Join Date
    Nov 2002
    Posts
    1,078

    Re: Explicitly calling destructor.

    Originally posted by anonytmouse
    I'm wondering:
    - Is calling the destructor explicitly the equivalent of the object going out of scope?
    not really as the object remains in memory, but initially, calling the destructor explicitly will work anyways -- sort of.

    The problem is that while you are explicitly calling the destructor, it will still be automatically called again once the object goes out of scope. That might not seem like too much of a problem but it is actually very big -- when the destructor is called the second time, the object is in an invalid state.

    For instance, normally in the destructor it may call a function on an object pointed to through a datamember, which will tell that object that your bitmap is now destructed. If the destructor gets called twice (as it will in your example), that will obviously cause problems. Generally you should only call the destructor explicitly if you are within a member function of that class or if its from another object who is closely tied to the implementation of the type of object whose destructor is being called. Otherwise you will have problems as you can't be certain of the state of the object after the initial destruction.

    Instead, if you want your bitmap to be destructed before your call, just put it in its own block:

    Code:
    {
      Bitmap bmpPdf(hBitmap, NULL);
      /*
        stuff
      */
    }
    DeleteObject(hBitmap);
    that way you are guaranteed bmpPdf is destructed before DeleteObject is called.
    Last edited by Polymorphic OOP; 03-11-2004 at 12:11 AM.

  3. #3
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    Thanks for the comrehensive and well written reply. I've used the block solution as suggested.

    It seems to be a limitation of C++ that there is no way to safely destroy a stack based object other than going out of scope. Doesn't it, in practise, mean that objects are left around after they are needed? And doesn't it encourage using inefficient heap based memory?

    Thanks.

  4. #4
    Programming Sex-God Polymorphic OOP's Avatar
    Join Date
    Nov 2002
    Posts
    1,078
    Originally posted by anonytmouse
    It seems to be a limitation of C++ that there is no way to safely destroy a stack based object other than going out of scope. Doesn't it, in practise, mean that objects are left around after they are needed? And doesn't it encourage using inefficient heap based memory?
    Not really. Because of the nature of a stack it is impossible to get rid of something not on the top (otherwise it wouldn't be a stack). Imagine this as being a representation of the stack in memory (not C++ code, just memory)

    Code:
    int    a
    double b
    char   c
    int    d
    in memory, those are all literally adjacent.

    if you were to try to take out b before c and d to be "efficient," that would mean you'd have to shift c and d over in memory (copying the data). While that could potentially work, assuming the objects are copied properly (with the copy constructor and then are destructed), you'd still have the problem that other pointers that can potentially be pointing to c or d will now be pointing to memory occupied by something else.

    In the end, it really only logically makes sense when working with a stack such as in C++ to add and remove items only from the top (hense the definition of a stack).

  5. #5
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    I'm not talking about removing the object from the stack(which can't be done in C either), I'm talking about releasing the resources an object holds - dynamically allocated memory, os handles, etc.

    Consider a Bitmap class. The struct itself may only be taking up a dozen bytes of stack but the bitmap it holds may take a dozen megabytes of dynamically allocated memory. It makes sense to get rid of it as quickly as possible.

    Ideally, objects which take up a large amount of resources would offer a dispose function but it would be a nice if there was a standard way of doing this.

    Assumably implementing this would mean a flag stored with each object(valid | not valid). Due to alignment issues this would probably have to be 4 bytes which is alright for single objects but may become a problem for large arrays. It would also complicate matters with invalid objects sitting around.

    Coming from C I guess I have to get used to losing, in part, C's primary feature: "Total Control ®".

    Thanks.

  6. #6
    Programming Sex-God Polymorphic OOP's Avatar
    Join Date
    Nov 2002
    Posts
    1,078
    Originally posted by anonytmouse
    I'm not talking about removing the object from the stack(which can't be done in C either), I'm talking about releasing the resources an object holds - dynamically allocated memory, os handles, etc.
    You can do that in C++ -- you just have a member function you can call to deallocate the data prior to destruction, as you were saying with a "dispose" function. If you really want to do it in a standard way and the object doesn't have a dispose function and for some reason you can't just make a new block (which usually makes the most logical sense), then you can always use placement new to construct an object on memory you allocate (IE make a char array of sizeof( type ) length on the stack ) and then destruct it whenever you want, but I really wouldn't recommend it.
    Last edited by Polymorphic OOP; 03-11-2004 at 01:40 AM.

  7. #7
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    You can destroy stack items in C/C++. The only things kept track of in a stack are the top and the number of items in the stack. The data items are not actually shuffled around, rather the stack pointer is moved to a new 'top'. Shuffling all the items around in memory would take far too many cycles. It is the TOS pointer that is moved. When the TOS reaches the last item....then that item really is the top item.

    I'm not sure how the stack class from STL actually works internally but most stacks function in this way.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 1
    Last Post: 06-10-2008, 08:38 PM
  2. Replies: 6
    Last Post: 01-17-2007, 12:07 PM
  3. Problem Calling Destructor, and prob with cin.
    By imortal in forum C++ Programming
    Replies: 2
    Last Post: 10-10-2003, 09:29 AM
  4. uhm... calling a destructor manually
    By *ClownPimp* in forum C++ Programming
    Replies: 2
    Last Post: 09-11-2002, 02:37 PM