From: "Tim 'Zastai' Van Holder" Newsgroups: comp.os.msdos.djgpp References: <8n6rv4$gkj$1 AT nnrp1 DOT deja DOT com> Subject: Re: Newbie problem with using exceptions Lines: 116 X-Priority: 3 X-MSMail-Priority: Normal X-Newsreader: Microsoft Outlook Express 5.00.2314.1300 X-MimeOLE: Produced By Microsoft MimeOLE V5.00.2314.1300 Message-ID: <_YWl5.48763$Fw6.1275597@afrodite.telenet-ops.be> Date: Mon, 14 Aug 2000 18:34:34 GMT NNTP-Posting-Host: 213.224.94.80 X-Trace: afrodite.telenet-ops.be 966278074 213.224.94.80 (Mon, 14 Aug 2000 20:34:34 MET DST) NNTP-Posting-Date: Mon, 14 Aug 2000 20:34:34 MET DST Organization: Pandora - Met vlotte tred op Internet To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp Reply-To: djgpp AT delorie DOT com wrote in message news:8n6rv4$gkj$1 AT nnrp1 DOT deja DOT com... > I've programmed some time in C and I'm trying to switch to > C++ and I'm having problems with using the exceptions. > DJGPP crashes when I try this: > > /*************************/ > class Obj > { > Obj() > { > throw 0; > } > }; > > int Test () > { > Obj *o; > > try { > o = new Obj; this should'nt compile - your constructor is private > } > catch (...) { > return -1; > } > > delete o; > return 0; > } > > int main () > { > if ( Test() != 0 ) > printf ( "\nError!" ); > return 0; > } > /*************************/ Once the constructor is made public, this compiles and runs fine for me (gcc 2.95.2). The only thing that I know of that causes gcc-compiled programs to abort rather ungraciously is throw without arguments. Normally this should mean 'rethrow', ie in this example, the 'throw;' makes sure the catch-all block gets run even if a string was caught: try { } catch(const char* s) { cout << "Caught a string (" << s << ')' << endl; throw; } catch(...) { } A gcc-compiled program will just abort when it hits the throw. > I know this is poor use of exceptions anyway, but would need > this kind of system because when I create objects, I can't > otherwise know if there was a problem in constructor. Can > anybody give me a hint how this should be done in the right > way. A cleaner way would be to have the constuctor do as little as possible and have a method that does the 'real' constructing job (and return its success). If this is not possible/acceptable, exceptions could be a decent way around things. You could also use a factory system, where a class' constructors are private and the only way to create one is through a static member of the class - this could allocate an object, then perform all the steps that would normally be done in the constructor, and then return a pointer to a new object, or 0 in case of failure. Example: // This is what you use class Foo1 { public: Foo1() { if(!MyClassSetup()) throw runtime_error("Oops - couldn't construct Foo1 class!"); } private: bool MyClassSetup(); }; // This is cleaner class Foo2 { public: static Foo2* createInstance(void) { Foo2* obj = new(nothrow) Foo2; if(obj && obj->MyClassSetup()) return obj; else return 0; } private: bool MyClassSetup(); Foo2() { } }; Of course, the call to MyClassSetup() here is just a placeholder for whatever operations you are performing in the constructor. Note, this is not something I've used so far, and is taken entirely from concepts I remember from textbooks, so it might not actually be accurate. Caveat lector. > By the way I would also like to know are you guys always > freeing up all the allocated memory when your program gets > an error, or are you just quitting with exit() or some > similar way? If there is an error in a function, I tend to free/delete all allocated memory/objects in that function, before leaving it. Everything else is the responsibility of the calling functions, or exit(), depending on how serious the error is (ie whether or not returning from the failed function is safe/acceptable).