another preference question....
-
El Corazon wrote:
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.
I agree. Otherwise, what's the point of having constructors/destructors? I would find it strange if I'm using an API in which I have to call "Initialize" on an object before I can use it. 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. It seems rather procedural rather than object oriented to have to remember to call "Initialize/Cleanup" on objects rather than letting the constructor/destructor handle that for you. Having said that, sometimes it's necessary to establish the relationships between objects after they've been created. This is particularly true when you must have a parameterless constructor for whatever reason. Once an object is created, you can then establish its relationship with other objects by using its setters to set its properties. However, even in those situations, it's helpful if the object behaves normally regardless of whether any of its properties have been set. The "Null Object" design pattern can be helpful here.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(); ...
-
Generally I think it's best to have the constructor/destructor perform the intilisation/clean up. Breaking the code out into an init procedure which is called from the constructor(s) can be useful for sharing similar code between constructors but otherwise it's a personal preference thing... However, there are times when init/cleanup methods are required. One example is when you want to support some kind of object pooling mechanism, in which case you'll want to be able to clean up the class without it be 'finalized' and you'll want to be able to re-initialize it when it's retreive back out of the pool - at which point the constructor is useless since the object has already been created. If initialisation is expensive, then you may also want to be able to create X number of classes in the pool (on startup for example) and allow the initialization to take place 'lazily' after the fact. Also, the 'clean up' style methods may be needed depending on what language you're working in. In something like C# where there is no deterministic finalization you need an explicit clean up method on some objects to allow immediate release of unmanaged resources (hence the IDisposable interface, which is really just a system supported way of implementing a clean up method). In VB6, circular references between classes could be a problem, in which case a clean up method would sometimes be needed to release at least one set of references so memory wasn't leaked and the classes did actually get 'finalized' eventually. I can't think of another instance when 'init' style methods are useful, except for the object pooling, although that might just be lack of imagination on my part :) Basically, I think it depends on that particular patterns and architecture you're using, but for mmost classes the constructors/destrutors are the right place for init/cleanup code.
I strongly dislike the create-and-then-initialize usage; as a general rule, I always leave the object in a well-known usable state after a new, so I support the initialization-as-sinonym-for-creation point of view. Actually, when I have the authority to set coding standards in the team I require that one of the tests the class must pass be a call to each of it's methods right after object creation to verify there are no internal state management issues unsolved. If your object requires a multi step initialization, which means it's a state-based class, I write another class that handles the creation (and the rest of it's state management, for that matter) of the "complex" one, in a way that that the "main app" code doesn't have to know "everything about everything". Te complexity is hidden in the "creator". In pattern language, that's called inversion of control (IoC). That's what the Factory pattern's "Create" methods are used generally for, instead of the "a = New A" approach. It hides the complexities associated to object creation. When an object instance has not-so-trivial-to-manage dependencies (memory, device or whatever they are) call the specialist. That's where we could get talking about Dependency Injection, but that's another story. So, even if your dependencies are trivial, call the specialist. I still haven't found a situation where that approach hasn't fit for me, so I keep applying the rule. I think any help to isolate and hide complexity from code structure must be the first issue from a developer point of view -from an analyst's it is to perform whatever task it's supposed to!). Also, that "constructor" class is the perfect place to comment the whole tricky part of the initialization, actually it should be the only place where any comment on it should appear. Of course, all this is just my opinion, although I think it's an informed one :) "I disagree with your every single word, but I'll defend to death your right to say them." - Voltaire
-
I think the init() concept ranks up there with initialization through property setters. X| Initialization in the constructor means that you can't have access to the object from outside code until the constructor completes unless you are doing something like an inplace new. Plus one of the biggest sources of C++ bugs is not calling delete, now you've just added this potential to stack allocated objects too. It's even worse for mutlithreaded code since you are just introducing the possibility of extra race conditions. So, I'd just require that every object with the init and clear methods implement 2 static methods:
object* Construct()
{
object* obj = new object();
obj->init();
return obj;
}void Destruct(object* obj)
{
obj->clear();
delete obj;
}Either that or add a init_ptr<> smart pointer class.
This blanket smells like ham
I like.
-- Time you enjoy wasting is not wasted time - Bertrand Russel
-
If you want to bring it up with the team again, and I would personally, the name of the pattern that you use is called Resource Acquisition Is Initialization. The best reason for using this pattern, in my opinion, is that it is exception safe. If an exception happens it the object will be cleaned up automatically when the destructor is called, without you having to specifically needing to call the cleanup method. A quick google search for RAII will bring up plenty of reasons to discuss with your team should you ever find yourself in that argument again.
Janzen wrote:
the pattern
OT: I think RAII is mostly considered to be an idiom, not a pattern.
-- Time you enjoy wasting is not wasted time - Bertrand Russel
-
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
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...
-
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)
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.
-
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)
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. ;)
-
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
:laugh: I don't know how I got those two mixed up. Frankly speaking, that's scary! :-D
-
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)
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.
-
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)
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!
-
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)
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
-
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
returnsNULL
, so there is nothing to calldelete
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 placementnew
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 thevtbl
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 placementnew
, 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 -
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)
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
-
Well there is nothing wrong with breaking that out like that as long as they are then called from constructors,destructors, assignment operators etc.
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 theirinit()
andclear()
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"
-
I like.
-- Time you enjoy wasting is not wasted time - Bertrand Russel
I hope that was humor, because my post definitely was.
This blanket smells like ham
-
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)
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.
-
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! | sighistAll 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.
-
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)
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.
-
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 theirinit()
andclear()
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"
-
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)
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.