Quote:Original post by instinKt Now I don't remember if I was having some unexpected issues, or if someone peered over my shoulder and said "don't do that", referring to the exceptions in the constructor. It had something to do with the fact that the memory would be allocated, but your "handle" to the object would not be assigned, because the constructor did not complete and you would end up with memory holes.
I've done some reading now and see that it's perfectly legal to throw in a constructor, which has really made me curious as to why I was told/found out otherwise. I found a hint that it may have once been true?
This is generally only a problem if you are using raw pointers and not using RAII in your code to ensure automagical clean up.
With RAII code and smart pointers if something fails in the constructor then you can throw an exception and everything will undo correctly without leaving 'holes' in memory.
Constructors always run the risk of failing for anything non-trivial anyway as any call to new runs the risk of throwing an exception (std::bad_alloc if memory serves), so unless you are going to avoid allocating memory in your constructor and say use an init function (generally a case of ewww!) you are always in danger of an exception occuring, which brings us back around to using RAII technics in code.
Quote:Original post by Nitage The destructor of an object doesn't get run if the constructor throws, but that's a reason to design the constructor properly - not a reason to avoid throwing from constructors.
Yes but from what I remember the (supposed) issue was that not only would the object's destructor not be called, but the memory for the object itself would not get freed. So even if you cleaned up any memory allocation you did in the constructor upon a fail, the memory for the object itself would be lost.
Has this ever been true? Or was the person/article/whatever I heard it from, interpreting the problem wrongly?
Quote:Original post by Nitage The destructor of an object doesn't get run if the constructor throws, but that's a reason to design the constructor properly - not a reason to avoid throwing from constructors.
Yes but from what I remember the (supposed) issue was that not only would the object's destructor not be called, but the memory for the object itself would not get freed. So even if you cleaned up any memory allocation you did in the constructor upon a fail, the memory for the object itself would be lost.
Has this ever been true? Or was the person/article/whatever I heard it from, interpreting the problem wrongly?
There could definitely have been pre-standard compilers with this behavior. However, the standard explicitly states what should happen to the memory:
Quote:C++ Standard, 5.3.4 New, §17 and §18
If any part of the object initialization described above terminates by throwing an exception and the new-expression does not contain a new-placement, then the deallocation function (_basic.stc.dynamic.deallocation_, _class.free_) is called to free the memory in which the object was being constructed, after which the exception continues to propagate in the context of the new-expression. If any part of the object initialization described above terminates by throwing an exception and the new-expression contains a new-placement, if the type of the object being created is a class type, a name lookup is performed on the name of operator delete using the same lookup rules as those used to find operator new (_class.free_). Otherwise, a name lookup is performed on the name of operator delete in the scope of the new-expression (or in global scope for ::new ). If the lookup succeeds and exactly one of the declarations found matches the decla- ration of that placement operator new, then the matching placement operator delete shall be called (_basic.stc.dynamic.deallocation_). If no matching placement delete is found, propagating the exception does not cause the object to be deleted.
Well, thank you all for the answers! I don't have a very good idea for what I'm going to make right now (some non-related boring work that I have to do first is keeping me busy), but at least I have a better idea for what not to do. Actually, I'm thinking about making a class that just places the whole file in a char stream or something like that (I'll take a look if something like that doesn't already exists in the std), than another class takes that stream and converts into a actual bitmap. The OO part is probably on how I make that arrangement work, but that is going to have to wait.
Oh, and another thing: I considered using throws, since I really wanted to learn how to use them, but I heard that the palm compiler that I'm using doesn't support try/catch properly, so I decided to ignore them (well yes, not the brightest idea on the book but...)