Code design in C++

Started by
13 comments, last by algumacoisaqualquer 16 years, 6 months ago
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.
Advertisement
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 Harry Hunt
static Bitmap* FromFile(std::string& fileName);


std::auto_ptr, especially the part about sources and sinks.

Quote:Original post by instinKt
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...)

Anyway, thank you all for the answers!

This topic is closed to new replies.

Advertisement