[comp.lang.c++] Calling constructors on already allocated data

faustus@dogwood.Berkeley.EDU (Wayne A. Christopher) (05/01/89)

Is it possible to call a constructor on data that has already been
allocated?  I have a buffer that I want to put some objects into,
but I don't know what objects and their order until runtime.  I can
think of a few ways to do this -- cast the contents of the pointer
into the type and let the casting function do the work, or create an
auto variable, then assign it to the contents of the buffer.  Is there
a better way?

	Wayne

shopiro@alice.UUCP (Jonathan Shopiro) (05/04/89)

In article <13096@pasteur.Berkeley.EDU>, faustus@dogwood.Berkeley.EDU (Wayne A. Christopher) writes:
> Is it possible to call a constructor on data that has already been
> allocated?  I have a buffer that I want to put some objects into,
> but I don't know what objects and their order until runtime.  I can
> think of a few ways to do this -- cast the contents of the pointer
> into the type and let the casting function do the work, or create an
> auto variable, then assign it to the contents of the buffer.  Is there
> a better way?
> 
> 	Wayne



I assume you mean ``call a constructor on _storage_ that has already been
allocated.''  This can be easily done with the new placement syntax.

First, put the following line in your header file.

	inline void*	operator new(long, void* p) { return p; }

[This syntax can be overloaded and generalized, but the above is appropriate
for your needs and most others.  Also, eventually you will have to replace
``long'' in the above with ``size_t'', an ANSI-ism.]

Then if p is a pointer to the storage you want to initialize as an
object of type X, you can write

	X*	xp = new (p) X(args);

where ``args'' is the argument list for the constructor.  You can invoke
the destructor on the object without de-allocating its storage with

	xp->X::~X();

Note that you are explicitly taking control of storage allocation here,
and abandoning the protection against improperly overlapping objects, etc.,
that is provided by the usual C++ mechanisms.  Therefore you should be
even more careful than usual when using this technique.
-- 
		Jonathan Shopiro
		AT&T Bell Laboratories, Warren, NJ  07060-0908
		research!shopiro   (201) 580-4229

shopiro@alice.UUCP (Jonathan Shopiro) (05/04/89)

In article <9298@alice.UUCP>, shopiro@alice.UUCP (Jonathan Shopiro) writes:
> First, put the following line in your header file.
> 
> 	inline void*	operator new(long, void* p) { return p; }
> 
It was pointed out to me that there is a supplied header file, new.h,
that makes this unnecessary.  If you use new.h, you will get the same
function, but it won't be called inline.  This has the disadvantage
that there is some performance penalty, but has the advantage that
you can replace the implementation (say to keep a log of allocations)
without re-compiling everything, and you can put a breakpoint on it.
-- 
		Jonathan Shopiro
		AT&T Bell Laboratories, Warren, NJ  07060-0908
		research!shopiro   (201) 580-4229