> Someone commented that 'the object is not constructed' if an exception > is thrown from the constructor, but that's not true.
This is true in C++ (unmanaged) - when a constructor throws an exception (while new is being performed), then just-allocated memory must be freed by the runtime. Since a caller will not receive a pointer, it will also be unable to free it manually (additionally, calling delete on such a pointer would be problematic). Of course, the memory allocated in a constructor will only be freed if appropriately arranged (e.g, using auto_ptr() or a similar schema). > It's true that a > reference to the new instance is not returned, but the instance is > always 'created' (I'm not sure what the definition is 'construction' is > in this case, but certainly an object id is allocated, etc.). This is > obviously the case, since you have access to the 'this' pointer inside > the constructor. Right - and I do not fully remember object initialization details, but when a constructor starts execution, the object has already its fields initialized (to default values or some other values), so it exists. Moreover, I believe that there is another difference from C++ - a base class' constructor may call virtual methods (that refer to not-yet-constructed derived class' object) - this is not elegant and this is an error in many cases, but is possible. In C++ (unmanaged), if my memory serves well, this is undefined and generally is a serious application error. Maybe due to different vtable initialization rules (mentioned in one of earlier posts). E.g., in C++, it is possible to call "pure virtual function" in such a way. > I hacked something together to check this out. As a result I've come up > with a new coding rule for myself: 'if the constructor is going to > throw, then the constructor has to guarantee that it hasn't configured > another instance with a reference to itself'. I would change this rule to the following: Do not pass a reference to itself anywhere until the object is fully functional (configured). Even if the constructor is "not going to throw" (theoretically, every line of code can throw something ;-) ), what will happen if other threads start using the object in an uninitialized state? What means that: - if a constructor has to pass a reference to itself, it will do it in "the last line of code" - care should be taken for non-sealed classes (!) > If you run this code, you'll see three partially constructed classes > handle the publisher's event. This is definitely something to watch out > for. I would say that they are completely constructed but not completely initialized (but will not fight for words). > At the end of the day, I tend to think of exceptions as being too > difficult to handle. I design my code such that exceptions don't happen. I think that you are going definitely too far. Exceptions are a great way of error reporting and handling, but as everything, there are always some problems involved. Are you still using the "old-good" C-style with a returned status? In a programming language with automatic GC? Interesting. > If they do, then I have a bug and I need to fix it, I don't pretend that > I can really 'handle' an exception (obviously there are cases where you > have to, but I try to avoid these), despite its politically correct name > I still consider it an 'error' and I generally terminate my process. To > try and handle all the possible states that you could be in when you > receive an exception seems almost impossible to me. How about ThreadInterruptedException? How about temporary communication errors? Etc. There are lots of errors that could be gracefully handled by an application. > // construct and detach three subscribers > for (Int32 i = 0; i < 3; i++) { > > try { > // try to construct a subscriber > subscriber = new EventSubscriber(publisher); > } > catch { > // ignore construction exception > } > > if (subscriber != null) { > // construction was successfull, now detatch > // NOTE: this won't execute in this example as construction > // is never successful, meaning we can't detach the > // subscriber > subscriber.Detach(); > } > } A small remark: Note that if the first object would succeed and the remaining two failed, then the first one would be Detach()ed three times. Marek =================================== This list is hosted by DevelopMentorŪ http://www.develop.com Some .NET courses you may be interested in: NEW! Guerrilla ASP.NET, 17 May 2004, in Los Angeles http://www.develop.com/courses/gaspdotnetls View archives and manage your subscription(s) at http://discuss.develop.com