Path: utzoo!attcan!uunet!mstan!jordan From: jordan@Morgan.COM (Jordan Hayes) Newsgroups: comp.lang.c++ Subject: Re: Handling trouble in C++ Message-ID: <352@s6.Morgan.COM> Date: 23 Aug 89 17:44:58 GMT References: <13262@well.UUCP> Reply-To: jordan@Morgan.COM (Jordan Hayes) Distribution: comp Organization: Morgan Stanley and Co., NY, NY Lines: 61 John Nagle asks: What then? Good question! I think your answer (3) is closest to what I do: 3. If the open fails, put the class instance into a "bad" state, so that later operations on it produce some error condition. This requires that all member functions call IsValid() or something before using this and continuing, storing the last error message, etc. and can make your code look ugly. For example: #define DEV "/dev/dialer" #define GOOD_TIME "1 800 424 9090" Frob *p; p = new Frob(DEV); if (p->status < 0) { Error("Frob(%s): %s\n", DEV, p->errStr); delete p; return; } p->Dial(GOOD_TIME); ... I asked a question a while back and got ZERO answers; it was along the lines of "how do you get a constructor to return NULL?" so that the above could be replaced with: if ((p = new Frob(DEV)) == NULL) { /* print error message */ return; } p->Dial(GOOD_TIME); Key to this: there must be no construction (note the explicit "delete" in the 1st example) if it "fails" ... Before C++, I used to write code that sorta did this, i.e., in the following code, the "new Frob" gets replaced with "MakeFrob": Frob * MakeFrob(d) char *d; { int fd; Frob *p; if ((fd = open(d, O_RDWR)) < 0) return((Frob *)NULL); p = malloc(sizeof(Frob)); p->fd = fd; return(p); } I miss it. /jordan