Path: utzoo!attcan!uunet!brunix!sdm From: sdm@cs.brown.edu (Scott Meyers) Newsgroups: comp.lang.c++ Subject: Re: Failed allocation in constructors? Keywords: exception handling Message-ID: <45157@brunix.UUCP> Date: 17 Jul 90 16:15:01 GMT References: <9075@goofy.Apple.COM> <860@grenada.UUCP> Sender: news@brunix.UUCP Reply-To: sdm@cs.brown.edu (Scott Meyers) Organization: Brown University Department of Computer Science Lines: 59 In article <860@grenada.UUCP> roger@grenada.uu.net (Roger Corman) writes: | C++ provides a way of intercepting failed calls to new(), via the | 'new() handler'. This allows deallocation of unnecessary storage and other | measures to be taken when memory allocation fails. This is a very void (*_new_handler)() isn't part of the language. It's mentioned only in passing in the ARM (E&S) in connection with the proposed exception handling facilities that C++ doesn't have yet. Instead, _new_handler is part of the AT&T implementation of C++. In short, you can't rely on it existing. | I can override new(), for each class. I suspect that this may offer | a solution but I haven't totally thought it through. I can live Given you have an AT&T implementation, you could declare a static class variable void (*class_new_handler)() and then rewrite operator new for each class as follows: void *operator new(size_t size) { void *ptr; _new_handler = class_new_handler; // set local handler ptr = ::new(size); // call global new _new_handler = default_handler; // unset local handler return ptr; // return allocated memory } | which allow for constructor failure. It would be nice if I could | specify, in the object definition, that it can only be created via new() | (possible enhancement to the language?). I typically test for This isn't as elegant as you'd like, but it's not too gruesome: class NewOnly { private: NewOnly(int params) { ... } // private constructor public: ~NewOnly() { ... } // public destructor static NewOnly *makeNewOnly(int params) // only way to make an object { return new NewOnly(params); } // from outside the class }; To create an object, you say NewOnly *p = NewOnly::makeNewOnly(args); and to delete it you say delete p; Good points: it works, and the compiler will flag usage errors. Bad points: the syntax is inconsistent with the usual way of creating objects, and members and friends of NewOnly can circumvent the private constructor. Scott sdm@cs.brown.edu