Path: utzoo!attcan!uunet!tut.cis.ohio-state.edu!snorkelwacker!bloom-beacon!eru!luth!sunic!tut!tukki!sakkinen From: sakkinen@tukki.jyu.fi (Markku Sakkinen) Newsgroups: comp.lang.c++ Subject: Re: An array of objects again! Message-ID: <3001@tukki.jyu.fi> Date: 13 Feb 90 10:14:53 GMT References: <1990Feb9.201223.14332@sdr.slb.com> <15100@cs.yale.edu> <10463@alice.UUCP> Reply-To: sakkinen@jytko.jyu.fi (Markku Sakkinen) Organization: University of Jyvaskyla, Finland Lines: 84 saito@sdr.slb.com (Naoki Saito) writes: > A long time ago, there was a discussion about the initializing the > array of objects. My question is slightly different from that. > Suppose I want to declare an array of object Cell. There are two ways to > declare this. > [largest part of article deleted] ================== starr-page@CS.YALE.EDU (Page Starr) replies: > You could consider: > (2.0) array of objects > Cell* pc = new Cell[N]; // null constructor. > for (int i = 0; i< N; i++) > new (pc[i]) Cell(i); // constructor with some argument. > > I believe the syntax is correct, but am not positive. This is known as > in-place initialization, and avoids the creation of temporaries. ================== shopiro@alice.UUCP (Jonathan Shopiro) replies to the original question (probably without having seen the second posting): > ... >= (2) array of objects >= Cell* pc = new Cell[N]; // null constructor. >= for (int i = 0; i < N; i++) >= pc[i] = *(new Cell(i)); // constructor with some argument. > This is surely not what you want to do. Each invocation of ``new Cell(i)'' > creates an object on the free store that will never be deleted. Instead > you can use a temp on the stack with the code > pc[i] = Cell(i); // constructor with some argument. > ... > What I would do in this case is the following > > (2.5) array of objects with re-constructor > Cell* pc = new Cell[N]; // null constructor. > for (int i = 0; i < N; i++) > pc[i].re_init(i); // re-constructor with some argument. > [some useful advice avoided] ================== Presumably the first poster has been accustomed to some other OO language, in which objects can be created only by calling "new" or some similar procedure. The case is quite opposite in C++: even objects of class types can, and normally should, belong to the automatic or the static (incl. external) storage class; they should be created in the heap (i.e. using "new") only when necessary. Remember that C++ has no garbage collection! That's what Shopiro hints at above. I suggest an improvement still over Shopiro's proposal in two ways: 1. There was no explicit reason given originally why the array should be allocated from the heap, so make the first line something like Cell cell_array [N]; (prepend 'static' if needed). Of course, this works only if N is a compile-time constant - if it's a variable, you must use "new". 2. As far as I understand from the new C++ Release 2.0 Reference Manual, it is now possible to initialise an array of class objects even with constructors that take arguments, _if_ the array is not created by "new". Thus a separate re-initialisation function will not be needed in a typical case. About Starr's proposal: The implications of additional arguments to "new" are hardly mentioned at all in the new Reference Manual, and only a little better in Stroustrup's paper, "The Evolution of C++: 1985 to 1989". What I surmise from that is that Starr's suggestion would _almost_ achieve its intended purpose, but it would allocate and initialise "unreachable" new objects on the second round. To avoid that, the additional argument to "new" should be cast to a _non-class_ type. Is this guess correct? Markku Sakkinen Department of Computer Science University of Jyvaskyla (a's with umlauts) Seminaarinkatu 15 SF-40100 Jyvaskyla (umlauts again) Finland SAKKINEN@FINJYU.bitnet (alternative network address)