Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. The Lounge
  3. another preference question....

another preference question....

Scheduled Pinned Locked Moved The Lounge
questionc++designcollaborationperformance
84 Posts 54 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Miszou

    Daniel Grunwald wrote:

    If the Create() method can return derived classes, I would put it in a factory class and not in the base class

    I agree. Like I said, it was a terrible contrived example, and after I posted it I realized how bad it actually was! Having a base class create derived classes would be a complete WTF... :-O


    Sunrise Wallpaper Project | The StartPage Randomizer | A Random Web Page

    D Offline
    D Offline
    Daniel Grunwald
    wrote on last edited by
    #59

    Miszou wrote:

    Having a base class create derived classes would be a complete WTF

    Well, you're not the first who wrote something like that. Take a look at System.Net.WebRequest.Create...

    1 Reply Last reply
    0
    • E El Corazon

      Just curious. Had this disagreement with my team a while back and lost. I didn't want to bring it up then as it would be pointless. But I am curious on a design issue with classes. I was brought up (admittedly on books for C++, not college), that constructors not only construct, but initialize everything so that the class is "ready to be used" alternately the destructor removes everything and cleans up after itself. This way there is never an issue as far as timing when you use the contents of a class. Others have promoted an init()/configure() methodology and cleanup()/clear() so that constructors construct the class, not the content, init()/configure() sets up the content, cleanup()/clear() removes the content (which I have used for specific reusable storage type classes, but never as a hard rule of everything) and destructor pretty much does nothing unless memory allocation is involved. Of course this also means, if threads are involved there requires an additional start() after configure() to get the ball rolling which creats a set of "do this first directives" in the documentation. :~ I do freely admit no college training, not sure if this is a college thing or not. I am not a lover of absolutes, but I did always like my classes clean so that they start and stop by scope properly (everything handled by constructors and destructors), and now I find myself staring at my code as if it is growing green, black and white mold with the recent changes to it. X| Is this a college teaching method? Have I been putting too much effort into organizing my classes as independant entities?

      _________________________ Asu no koto o ieba, tenjo de nezumi ga warau. Talk about things of tomorrow and the mice in the ceiling laugh. (Japanese Proverb)

      T Offline
      T Offline
      tec goblin
      wrote on last edited by
      #60

      Regarding the original question, at uni we learnt to do all this in the constructor. Well, it's just a uni @ Greece... I often separate it into different methods (create data bindings, load a tree etc), but still they are all called from the constructor, except from cases of winforms where you have a constructor and a Load.

      1 Reply Last reply
      0
      • E El Corazon

        Just curious. Had this disagreement with my team a while back and lost. I didn't want to bring it up then as it would be pointless. But I am curious on a design issue with classes. I was brought up (admittedly on books for C++, not college), that constructors not only construct, but initialize everything so that the class is "ready to be used" alternately the destructor removes everything and cleans up after itself. This way there is never an issue as far as timing when you use the contents of a class. Others have promoted an init()/configure() methodology and cleanup()/clear() so that constructors construct the class, not the content, init()/configure() sets up the content, cleanup()/clear() removes the content (which I have used for specific reusable storage type classes, but never as a hard rule of everything) and destructor pretty much does nothing unless memory allocation is involved. Of course this also means, if threads are involved there requires an additional start() after configure() to get the ball rolling which creats a set of "do this first directives" in the documentation. :~ I do freely admit no college training, not sure if this is a college thing or not. I am not a lover of absolutes, but I did always like my classes clean so that they start and stop by scope properly (everything handled by constructors and destructors), and now I find myself staring at my code as if it is growing green, black and white mold with the recent changes to it. X| Is this a college teaching method? Have I been putting too much effort into organizing my classes as independant entities?

        _________________________ Asu no koto o ieba, tenjo de nezumi ga warau. Talk about things of tomorrow and the mice in the ceiling laugh. (Japanese Proverb)

        S Offline
        S Offline
        seeitsharper
        wrote on last edited by
        #61

        By the very nature of it being a constructor it is supposed to construct the object. Now what ever language you use it should be in a valid state after construction, but there are some things that incure too much of an overhead to be placed inside a constructor. I would avoid starting threads or calling services in there as it makes it very hard to use in the calling code as you may want to pass the reference around. Having said that the behaviour of the class may change if a thread is not started so either well document it, and/or think about more about how the class is going to be used and design it accordingly. ;)

        1 Reply Last reply
        0
        • J Johann Gerell

          Joergen Sigvardsson wrote:

          RIAA

          But you mean RAII, of course. Perhaps _the_ most important four-letter word in OO/C++. :rolleyes:

          -- Time you enjoy wasting is not wasted time - Bertrand Russel

          J Offline
          J Offline
          Jorgen Sigvardsson
          wrote on last edited by
          #62

          :laugh: I don't know how I got those two mixed up. Frankly speaking, that's scary! :-D

          1 Reply Last reply
          0
          • E El Corazon

            Just curious. Had this disagreement with my team a while back and lost. I didn't want to bring it up then as it would be pointless. But I am curious on a design issue with classes. I was brought up (admittedly on books for C++, not college), that constructors not only construct, but initialize everything so that the class is "ready to be used" alternately the destructor removes everything and cleans up after itself. This way there is never an issue as far as timing when you use the contents of a class. Others have promoted an init()/configure() methodology and cleanup()/clear() so that constructors construct the class, not the content, init()/configure() sets up the content, cleanup()/clear() removes the content (which I have used for specific reusable storage type classes, but never as a hard rule of everything) and destructor pretty much does nothing unless memory allocation is involved. Of course this also means, if threads are involved there requires an additional start() after configure() to get the ball rolling which creats a set of "do this first directives" in the documentation. :~ I do freely admit no college training, not sure if this is a college thing or not. I am not a lover of absolutes, but I did always like my classes clean so that they start and stop by scope properly (everything handled by constructors and destructors), and now I find myself staring at my code as if it is growing green, black and white mold with the recent changes to it. X| Is this a college teaching method? Have I been putting too much effort into organizing my classes as independant entities?

            _________________________ Asu no koto o ieba, tenjo de nezumi ga warau. Talk about things of tomorrow and the mice in the ceiling laugh. (Japanese Proverb)

            M Offline
            M Offline
            MCEdwards
            wrote on last edited by
            #63

            One advantage of using the Init() method comes from being able to subscribe to the an Event that is fired when the class values are initiated. If you want an series of events to fire immediately after the class has been initialized this would not be possible using a constructor. Using an Init() you can create the class, subscribe events and then populate the data. So imagine that you new class is passed through a set of methods, you may not know at what time within the methods it is being populated but you can still capture the event a perform some action upon it. To be honest I have yet to use this type of setup and have found that using constructors is more than sufficient.

            1 Reply Last reply
            0
            • E El Corazon

              Just curious. Had this disagreement with my team a while back and lost. I didn't want to bring it up then as it would be pointless. But I am curious on a design issue with classes. I was brought up (admittedly on books for C++, not college), that constructors not only construct, but initialize everything so that the class is "ready to be used" alternately the destructor removes everything and cleans up after itself. This way there is never an issue as far as timing when you use the contents of a class. Others have promoted an init()/configure() methodology and cleanup()/clear() so that constructors construct the class, not the content, init()/configure() sets up the content, cleanup()/clear() removes the content (which I have used for specific reusable storage type classes, but never as a hard rule of everything) and destructor pretty much does nothing unless memory allocation is involved. Of course this also means, if threads are involved there requires an additional start() after configure() to get the ball rolling which creats a set of "do this first directives" in the documentation. :~ I do freely admit no college training, not sure if this is a college thing or not. I am not a lover of absolutes, but I did always like my classes clean so that they start and stop by scope properly (everything handled by constructors and destructors), and now I find myself staring at my code as if it is growing green, black and white mold with the recent changes to it. X| Is this a college teaching method? Have I been putting too much effort into organizing my classes as independant entities?

              _________________________ Asu no koto o ieba, tenjo de nezumi ga warau. Talk about things of tomorrow and the mice in the ceiling laugh. (Japanese Proverb)

              K Offline
              K Offline
              kjude
              wrote on last edited by
              #64

              Just about everything to do with software design is a matter of opinion. Never feel that your's is worth less than other people's just because you didn't go to college. I never studied formally either. Everything I know about software design has been self taught or learned on the job. I've worked with lots of other developers since i started in this profession, and I find that it's real experience that counts here, not paper qualifications!

              1 Reply Last reply
              0
              • E El Corazon

                led mike wrote:

                Well there is nothing wrong with breaking that out like that as long as they are then called from constructors,destructors, assignment operators etc.

                nope, called from outside.... myclass = new aclass(...); myclass->init(); myclass->start(); // if threads myclass->stop(); // if threads myclass->clear(); delete(myclass);

                _________________________ Asu no koto o ieba, tenjo de nezumi ga warau. Talk about things of tomorrow and the mice in the ceiling laugh. (Japanese Proverb)

                H Offline
                H Offline
                Howard Richards
                wrote on last edited by
                #65

                As Mrs Thatcher once said.. "No No No!"[^] If Init() is something that should always be performed on a class before being used then it should be part of/called by the constructor. It should only be called/callable by the outside 'user' if it's optional. What happens if the user forgets to call init? or clear? Why make them remember when you can encapsulate that behaviour. This is why we have encapsulation..! As for clear, same principle applies, or use IDisposable if required.

                'Howard

                1 Reply Last reply
                0
                • J James R Twine

                  Bijesh wrote:

                  For example, if you are using a pointer, and the constructor thew an exception, do you delete the object through that pointer?

                  If the object was allocated using the non-placement (i.e. normal) version of new, the object is supposed to be "undone".  However (last checked on VC++ 6.0), members of that object will only be cleaned up if they themselves were fully constructed at the time of the exception, so the object is destructed (as best it could be), new returns NULL, so there is nothing to call delete on.    If the object was allocated on the stack, that stack context will be destroyed by the stack unwinding that takes place, so again there is nothing to manually destroy/cleanup.    Things change when you are dealing with placement new because you are basically directly calling the constructor to construct an object in a pre-allocated block of memory.  What you do in that case depends on what you are using the block of memory for.  You may free the entire block, or simply log the exception and continue with the next object reusing that block of memory.  You just have to watch out for that exception so that you do not end up using that "partially constructed" object (which I have done before :doh: - that is why I know it is possible, and know that the vtbl is/was the last thing to get initialized during construction).    Not many developers need to implement their own fixed-size-block-allocator-based object cache, or otherwise deal with placement new, so issues with throwing exceptions from constructors is a non-issue for many.    Peace!

                  -=- James
                  Please rate this message - let me know if I helped or not! * * * If you think it costs a lot to do it right, just wait until you find out how much it costs to do it wrong!
                  Avoid driving a vehicle taller than you and remember that Professional Driver on Closed Course does not mean your Dumb Ass on a Public Road!
                  See DeleteFXPFiles

                  B Offline
                  B Offline
                  Bijesh
                  wrote on last edited by
                  #66

                  Very interesting info! Thanks.. Bijesh

                  1 Reply Last reply
                  0
                  • E El Corazon

                    Just curious. Had this disagreement with my team a while back and lost. I didn't want to bring it up then as it would be pointless. But I am curious on a design issue with classes. I was brought up (admittedly on books for C++, not college), that constructors not only construct, but initialize everything so that the class is "ready to be used" alternately the destructor removes everything and cleans up after itself. This way there is never an issue as far as timing when you use the contents of a class. Others have promoted an init()/configure() methodology and cleanup()/clear() so that constructors construct the class, not the content, init()/configure() sets up the content, cleanup()/clear() removes the content (which I have used for specific reusable storage type classes, but never as a hard rule of everything) and destructor pretty much does nothing unless memory allocation is involved. Of course this also means, if threads are involved there requires an additional start() after configure() to get the ball rolling which creats a set of "do this first directives" in the documentation. :~ I do freely admit no college training, not sure if this is a college thing or not. I am not a lover of absolutes, but I did always like my classes clean so that they start and stop by scope properly (everything handled by constructors and destructors), and now I find myself staring at my code as if it is growing green, black and white mold with the recent changes to it. X| Is this a college teaching method? Have I been putting too much effort into organizing my classes as independant entities?

                    _________________________ Asu no koto o ieba, tenjo de nezumi ga warau. Talk about things of tomorrow and the mice in the ceiling laugh. (Japanese Proverb)

                    V Offline
                    V Offline
                    Vishal Doshi
                    wrote on last edited by
                    #67

                    I've found that using only constructors is the most recommended appraoch (RAII - Resource Acquisition is Initialization). However, there are cases when you need Init() for instance if you want to construct some bits in one thread and some bits in another thread. Another example is a File object. File->Open() is really the init operation. The file object could be created with no attached file... The solutions I've used are: 1) Try as far as possible to always initialize fully in the constructor 2) When it is not possible -> Create a factory. For example: class FileFactory { FileFactory(string sDirectory); File CreateFile(string Filename) } which allows you to ensure that File objects are always fully initialised. 3) When neither approach is possible - or you create a FactoryFactoryFactory :) - create an Init() method - but then make sure that all class methods "check" that the object is in the correc state and throw if not. This makes the classes brittle - but - means that people forgetting to call Init() will atleast generate meaningfull error messages. -Vishal

                    1 Reply Last reply
                    0
                    • L led mike

                      Well there is nothing wrong with breaking that out like that as long as they are then called from constructors,destructors, assignment operators etc.

                      A Offline
                      A Offline
                      Anna Jayne Metcalfe
                      wrote on last edited by
                      #68

                      led mike wrote:

                      Well there is nothing wrong with breaking that out like that as long as they are then called from constructors,destructors, assignment operators etc.

                      One thing to be aware of is that doing so causes double initialisation (the default initialiser, then the init() called from the constructor. The only way to prevent that is to initialise class data in the constructor's initialiser list. Other than that, I've no issue with this approach except where someone then makes their init() and clear() virtual and calls them from constructors/destructor. This is such a bad idea in C++ it should cause a syntax error. X|

                      Anna :rose: Linting the day away :cool: Anna's Place | Tears and Laughter "If mushy peas are the food of the devil, the stotty cake is the frisbee of God"

                      L 1 Reply Last reply
                      0
                      • J Johann Gerell

                        I like.

                        -- Time you enjoy wasting is not wasted time - Bertrand Russel

                        A Offline
                        A Offline
                        Andy Brummer
                        wrote on last edited by
                        #69

                        I hope that was humor, because my post definitely was.


                        This blanket smells like ham

                        1 Reply Last reply
                        0
                        • E El Corazon

                          Just curious. Had this disagreement with my team a while back and lost. I didn't want to bring it up then as it would be pointless. But I am curious on a design issue with classes. I was brought up (admittedly on books for C++, not college), that constructors not only construct, but initialize everything so that the class is "ready to be used" alternately the destructor removes everything and cleans up after itself. This way there is never an issue as far as timing when you use the contents of a class. Others have promoted an init()/configure() methodology and cleanup()/clear() so that constructors construct the class, not the content, init()/configure() sets up the content, cleanup()/clear() removes the content (which I have used for specific reusable storage type classes, but never as a hard rule of everything) and destructor pretty much does nothing unless memory allocation is involved. Of course this also means, if threads are involved there requires an additional start() after configure() to get the ball rolling which creats a set of "do this first directives" in the documentation. :~ I do freely admit no college training, not sure if this is a college thing or not. I am not a lover of absolutes, but I did always like my classes clean so that they start and stop by scope properly (everything handled by constructors and destructors), and now I find myself staring at my code as if it is growing green, black and white mold with the recent changes to it. X| Is this a college teaching method? Have I been putting too much effort into organizing my classes as independant entities?

                          _________________________ Asu no koto o ieba, tenjo de nezumi ga warau. Talk about things of tomorrow and the mice in the ceiling laugh. (Japanese Proverb)

                          _ Offline
                          _ Offline
                          __Nick
                          wrote on last edited by
                          #70

                          My .02. Having an init function that is required to be called outside of the constructor is only useful in three situations 1 - When you have multiple constructors that all perform a set of common steps in addition to the custom steps that require different constructors. Moving the common steps to an init() function and calling it from the constructor makes for more modular code. 2 - When you are designing a class at the base of a class hierarchy that will need custom initialization before it can be used. Making init virtual and _NOT_ calling it from the constructor will perform the custom initialization. (Calling init from the base class in a constructor is BASE::init and not DERIVED::init). This can usually be done in a different manner. 3 - The class manages an expensive resource (or requires additional function calls to set parameters - username/password), and can't/shouldn't be ready for use on initialization. Usually the expensive resource scenario involves not a call to init(), but a call to open() or something similar. The username/password is similar, but I've seen always open socket designs that require authentication, but in those cases the init took the credentials. Regardless of what any book says I think that calling Some_Type * c = new SomeType(); c->init(); // Use some type here c->cleanup(); delete c; Is unnecessary, creates more of an opportunity to screw up, and ultimately just involves a wasted function call. In general if you have two steps that should always follow each other with nothing in between, they should be encapsulated to make sure that you always do so. Not doing so does not add any appreciable benefit. Debugging should be easier b/c everything is properly initialized, rather than it being seperated out.

                          1 Reply Last reply
                          0
                          • P peterchen

                            Very good criterion to separate these. HOWEVER, (muhahahah!)

                            Joergen Sigvardsson wrote:

                            the destruction of handled object may fail - something I don't want to deal with in a destructor

                            however, if the caller doesn't call Close() - because he's lazy or an exception got into the way, you still have to deal with that.

                            Joergen Sigvardsson wrote:

                            Also, I might want to be able to share the handled object between handles, or I might just want to transfer the responsibility of it elsewhere.

                            But Joergen! That's why there is shared_ptr!


                            We are a big screwed up dysfunctional psychotic happy family - some more screwed up, others more happy, but everybody's psychotic joint venture definition of CP
                            My first real C# project | Linkify!|FoldWithUs! | sighist

                            B Offline
                            B Offline
                            Big Endian 1
                            wrote on last edited by
                            #71

                            All class members must be initialized in the constructor initialization list. This is a C++ best practice. Don't count on the user to do stuff for you, your class must be self initialized to eliminate unexpected behaviours. As for destructors, there is nothing wrong by making a private cleanup method and calling within the destructor.

                            1 Reply Last reply
                            0
                            • E El Corazon

                              Just curious. Had this disagreement with my team a while back and lost. I didn't want to bring it up then as it would be pointless. But I am curious on a design issue with classes. I was brought up (admittedly on books for C++, not college), that constructors not only construct, but initialize everything so that the class is "ready to be used" alternately the destructor removes everything and cleans up after itself. This way there is never an issue as far as timing when you use the contents of a class. Others have promoted an init()/configure() methodology and cleanup()/clear() so that constructors construct the class, not the content, init()/configure() sets up the content, cleanup()/clear() removes the content (which I have used for specific reusable storage type classes, but never as a hard rule of everything) and destructor pretty much does nothing unless memory allocation is involved. Of course this also means, if threads are involved there requires an additional start() after configure() to get the ball rolling which creats a set of "do this first directives" in the documentation. :~ I do freely admit no college training, not sure if this is a college thing or not. I am not a lover of absolutes, but I did always like my classes clean so that they start and stop by scope properly (everything handled by constructors and destructors), and now I find myself staring at my code as if it is growing green, black and white mold with the recent changes to it. X| Is this a college teaching method? Have I been putting too much effort into organizing my classes as independant entities?

                              _________________________ Asu no koto o ieba, tenjo de nezumi ga warau. Talk about things of tomorrow and the mice in the ceiling laugh. (Japanese Proverb)

                              S Offline
                              S Offline
                              SecondBreakfast
                              wrote on last edited by
                              #72

                              I got in the habit of doing very little in constructors in C++ because they don't have a return value and it was difficult to know if an error occurred during the initialization process. But, this was back when exceptions only existed in the MFC library as primitive "set/jump" implementation (no clean up). In those days it made more sense to just initialize member varialbes and use a seperate init() method to do any heavy lifting. Then if something failed, the init() could return some meaningful information and the caller could do something intelligent. However, now with structured exception handling, garbage collection, etc, it's makes more sense to do the work in the constructor in most cases. Nevertheless, I'd still argue that it's not bad design to limit the constructor to simple variable initialization and seperate out more complex initialization operations to another step in some situations. I know, what situations? Any situation where you don't want to handle an error condition by simply throwing a exception to the caller.

                              1 Reply Last reply
                              0
                              • A Anna Jayne Metcalfe

                                led mike wrote:

                                Well there is nothing wrong with breaking that out like that as long as they are then called from constructors,destructors, assignment operators etc.

                                One thing to be aware of is that doing so causes double initialisation (the default initialiser, then the init() called from the constructor. The only way to prevent that is to initialise class data in the constructor's initialiser list. Other than that, I've no issue with this approach except where someone then makes their init() and clear() virtual and calls them from constructors/destructor. This is such a bad idea in C++ it should cause a syntax error. X|

                                Anna :rose: Linting the day away :cool: Anna's Place | Tears and Laughter "If mushy peas are the food of the devil, the stotty cake is the frisbee of God"

                                L Offline
                                L Offline
                                led mike
                                wrote on last edited by
                                #73

                                Anna-Jayne Metcalfe wrote:

                                the default initialiser

                                Not sure what you mean?

                                1 Reply Last reply
                                0
                                • E El Corazon

                                  Just curious. Had this disagreement with my team a while back and lost. I didn't want to bring it up then as it would be pointless. But I am curious on a design issue with classes. I was brought up (admittedly on books for C++, not college), that constructors not only construct, but initialize everything so that the class is "ready to be used" alternately the destructor removes everything and cleans up after itself. This way there is never an issue as far as timing when you use the contents of a class. Others have promoted an init()/configure() methodology and cleanup()/clear() so that constructors construct the class, not the content, init()/configure() sets up the content, cleanup()/clear() removes the content (which I have used for specific reusable storage type classes, but never as a hard rule of everything) and destructor pretty much does nothing unless memory allocation is involved. Of course this also means, if threads are involved there requires an additional start() after configure() to get the ball rolling which creats a set of "do this first directives" in the documentation. :~ I do freely admit no college training, not sure if this is a college thing or not. I am not a lover of absolutes, but I did always like my classes clean so that they start and stop by scope properly (everything handled by constructors and destructors), and now I find myself staring at my code as if it is growing green, black and white mold with the recent changes to it. X| Is this a college teaching method? Have I been putting too much effort into organizing my classes as independant entities?

                                  _________________________ Asu no koto o ieba, tenjo de nezumi ga warau. Talk about things of tomorrow and the mice in the ceiling laugh. (Japanese Proverb)

                                  C Offline
                                  C Offline
                                  CBJG
                                  wrote on last edited by
                                  #74

                                  Unless there is a compelling reason for using an init() function, it is really a waste of time and bad coding practice. However, there are instances where it is needed, or is much simpler to use an init() function. I do real-time, embedded programming and most of the classes have init() functions. The reason is that memory is statically allocated and fixed and initializing classes via constructors does not guarantee what order the classes are initialized in. Therefore, if a class depends on another class being set up already, for example (there are other reasons as well), the init() functions can be called after all the necessary set up is done. This guarantees that it is known precisely when the classes start running.

                                  1 Reply Last reply
                                  0
                                  • O objarni

                                    Leslie Sanford wrote:

                                    Regarding destructors, I program mainly with C# now, and I miss the deterministic and automatic destruction mechanism of C++. Instead, I must remember to call Dispose where it is implemented.

                                    A little of topic, but I thought it was worth mentioning; Well -- Dispose() will be called by the garbage collector in any case -- so you don't really need to call it, unless you REALLY want to control the timing of the cleaning up of you resource. If I have such a scarce resource, say a database connection, that I really want to be cleaned up right now and not "in a couple of seconds", I use the C# keyword "using" this way: using(DatabaseConnection conn = DatabaseConnection.CreateInstance()) { ... } .. which automatically calls the Dispose() method of conn when exiting the code block {...} . Note that using() requires the declared object (conn here) to implement the IDisposable() interface. Even if I skipped the using() clause, conn.Dispose() would have been called when the garbage collector "thrashed" the conn some seconds later: DatabaseConnection conn = DatabaseConnection.CreateInstance(); ...

                                    L Offline
                                    L Offline
                                    Leslie Sanford
                                    wrote on last edited by
                                    #75

                                    objarni wrote:

                                    Well -- Dispose() will be called by the garbage collector in any case -- so you don't really need to call it, unless you REALLY want to control the timing of the cleaning up of you resource.

                                    Clearly I need to brush up on my .NET knowledge. I was under the impression that you must call Dispose yourself. Here's the pattern I've learned from .NET documentation, at least when the class that implements IDisposable can be used as a base class:

                                    public class SomeClass : IDisposable
                                    {
                                    ~SomeClass()
                                    {
                                    Dispose(false);
                                    }

                                    protected virtual void Dispose(bool disposing)
                                    {
                                        if(disposing)
                                        {
                                            // Release managed resources as well as unmanged ones.
                                        }
                                        else
                                        {
                                            // Release only unmanaged resources if they have not 
                                            // been released already.
                                        }
                                    }
                                    
                                    public void Dispose()
                                    {
                                        Dispose(true);
                                    
                                        GC.SuppressFinalizer(this);  
                                    }
                                    

                                    }

                                    My impression, which is apparently wrong, is that it's up to you to call Dispose(). If you do, you should call Dispose(bool disposing), passing a true value indicating that the call is coming from Dispose() and not the finalizer. In addition, in our Dispose() method we tell the garbage collector not to call the finalizer since we've taken care of everything ourselves. However, if we forget to call Dispose(), the finalizer still gets called. In the finalizer, we call Dispose(bool disposing) passing the false value indicating that it's being called by the garbage collector and should only release any unmanaged resources that have not already been released. So what you're saying is that the garbage collector will call Dispose() in any case? [EDIT]Just to qualify things, I understand that Dispose() will be called automatically when using the, um, using construct. I'm wondering about other situations in which you may forget to call Dispose() yourself and you don't have the using construct taking care of it for you.[/EDIT]

                                    O 1 Reply Last reply
                                    0
                                    • E El Corazon

                                      Just curious. Had this disagreement with my team a while back and lost. I didn't want to bring it up then as it would be pointless. But I am curious on a design issue with classes. I was brought up (admittedly on books for C++, not college), that constructors not only construct, but initialize everything so that the class is "ready to be used" alternately the destructor removes everything and cleans up after itself. This way there is never an issue as far as timing when you use the contents of a class. Others have promoted an init()/configure() methodology and cleanup()/clear() so that constructors construct the class, not the content, init()/configure() sets up the content, cleanup()/clear() removes the content (which I have used for specific reusable storage type classes, but never as a hard rule of everything) and destructor pretty much does nothing unless memory allocation is involved. Of course this also means, if threads are involved there requires an additional start() after configure() to get the ball rolling which creats a set of "do this first directives" in the documentation. :~ I do freely admit no college training, not sure if this is a college thing or not. I am not a lover of absolutes, but I did always like my classes clean so that they start and stop by scope properly (everything handled by constructors and destructors), and now I find myself staring at my code as if it is growing green, black and white mold with the recent changes to it. X| Is this a college teaching method? Have I been putting too much effort into organizing my classes as independant entities?

                                      _________________________ Asu no koto o ieba, tenjo de nezumi ga warau. Talk about things of tomorrow and the mice in the ceiling laugh. (Japanese Proverb)

                                      M Offline
                                      M Offline
                                      Momony
                                      wrote on last edited by
                                      #76

                                      Reason's why you might want an initialize and cleanup routines separate from constructors. 1) Your class has many constructors to handle argument type conversion, or allows multiple ways to "start-up" the object. In these situations, it is common to have a bunch of initialization code that is common to all of the constructors, and it is preferred to create 1 private function which all of the constructor's call after handling their special initialization circumstances. 2) Your class has some resources that have no performance penalty to declare, but have a significant performance penalty if they are going to be used, and there are many instances in which the class can be used without using the performance heavy resources. Then you would want to separate the initialization of the performance heavy resources to make it optional. I think an example of this is the CWnd class in MFC C++ 4.2. There are a lot of things you can do with a CWnd that don't require a Window Handle to be created (which causes a lot of OS overhead). Thus, the model was you construct a CWnd object, and if you wanted to use the features requiring a handle, then you called the create function. 3) For cleanup, sometimes you want you object to exist, but you want to free the resources independently. This usually happens when you are "reusing" an existing object instead of deleting the object and creating a new one. Thus, by calling a clean-up function, you can essentially "reinitialize" the object to the constructed state without having to reconstruct the object. I think these situations are rare, and not necessarily the best design, and usually occur in applications needing the highest performance. Performance is rarely a good argument for complicating a class design, but sometimes you really do need it. However, consistency of class design is a good thing in a project, so if all the classes are construct / initialize / clear / destruct that is better than some you do that way, and some you dont. Now the question of if the initialization and clear routines need to be public is another question. Hope this helps, -Kent

                                      1 Reply Last reply
                                      0
                                      • E El Corazon

                                        Just curious. Had this disagreement with my team a while back and lost. I didn't want to bring it up then as it would be pointless. But I am curious on a design issue with classes. I was brought up (admittedly on books for C++, not college), that constructors not only construct, but initialize everything so that the class is "ready to be used" alternately the destructor removes everything and cleans up after itself. This way there is never an issue as far as timing when you use the contents of a class. Others have promoted an init()/configure() methodology and cleanup()/clear() so that constructors construct the class, not the content, init()/configure() sets up the content, cleanup()/clear() removes the content (which I have used for specific reusable storage type classes, but never as a hard rule of everything) and destructor pretty much does nothing unless memory allocation is involved. Of course this also means, if threads are involved there requires an additional start() after configure() to get the ball rolling which creats a set of "do this first directives" in the documentation. :~ I do freely admit no college training, not sure if this is a college thing or not. I am not a lover of absolutes, but I did always like my classes clean so that they start and stop by scope properly (everything handled by constructors and destructors), and now I find myself staring at my code as if it is growing green, black and white mold with the recent changes to it. X| Is this a college teaching method? Have I been putting too much effort into organizing my classes as independant entities?

                                        _________________________ Asu no koto o ieba, tenjo de nezumi ga warau. Talk about things of tomorrow and the mice in the ceiling laugh. (Japanese Proverb)

                                        P Offline
                                        P Offline
                                        patbob
                                        wrote on last edited by
                                        #77

                                        I learned as you. It prevents people from forgetting to init()/cleanup() the instances. If implemented right, it saves a lot of testing within the code to see if the object has been initialized, and if the initialization succeeded resulting in smaller, tighter, cleaner, easier to maintain code. ... of course, can't do it with C# since we no longer have the ability to control destruction timing. We're doomed to repeat, I guess.

                                        patbob

                                        1 Reply Last reply
                                        0
                                        • E El Corazon

                                          Just curious. Had this disagreement with my team a while back and lost. I didn't want to bring it up then as it would be pointless. But I am curious on a design issue with classes. I was brought up (admittedly on books for C++, not college), that constructors not only construct, but initialize everything so that the class is "ready to be used" alternately the destructor removes everything and cleans up after itself. This way there is never an issue as far as timing when you use the contents of a class. Others have promoted an init()/configure() methodology and cleanup()/clear() so that constructors construct the class, not the content, init()/configure() sets up the content, cleanup()/clear() removes the content (which I have used for specific reusable storage type classes, but never as a hard rule of everything) and destructor pretty much does nothing unless memory allocation is involved. Of course this also means, if threads are involved there requires an additional start() after configure() to get the ball rolling which creats a set of "do this first directives" in the documentation. :~ I do freely admit no college training, not sure if this is a college thing or not. I am not a lover of absolutes, but I did always like my classes clean so that they start and stop by scope properly (everything handled by constructors and destructors), and now I find myself staring at my code as if it is growing green, black and white mold with the recent changes to it. X| Is this a college teaching method? Have I been putting too much effort into organizing my classes as independant entities?

                                          _________________________ Asu no koto o ieba, tenjo de nezumi ga warau. Talk about things of tomorrow and the mice in the ceiling laugh. (Japanese Proverb)

                                          J Offline
                                          J Offline
                                          Jacek Ostrowski
                                          wrote on last edited by
                                          #78

                                          There is one important reason to use virtual Init() methods in C++ -- if you want to let descendant classes override initialization procedure, you cannot call it from constructor. C++ always completely constructs base class before it sets VMT pointer to the descendant class VMT, so it always calls virtual methods from the class being constructed. Delphi, for example, behaves differently -- you can call descendant class' virtual methods from constructor. jacostro

                                          1 Reply Last reply
                                          0
                                          Reply
                                          • Reply as topic
                                          Log in to reply
                                          • Oldest to Newest
                                          • Newest to Oldest
                                          • Most Votes


                                          • Login

                                          • Don't have an account? Register

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • World
                                          • Users
                                          • Groups