🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.std.c++
Article #3292

Re: proposal: renew & relocator member fn

#3292
From: Dietmar Kuehl
Date: Mon, 12 Feb 1996 07:17
116 lines
5858 bytes
Hi,

Gregory Bond <gnb@bby.com.au> wrote:
> People often ask for a "renew[]" operator to complement "new[]" in the
> same way realloc() complements malloc().  Of course the problem there
> is contructing the new objects and destructing the old ones, so a
> whole bunch of code gets written to do a new[], a bunch of assigns and a
> delete[]. This (or the moral equivalent using malloc(), placement new
> and delete) is especially prevalent inside container classes such
> as STL.

I can only see one (minor) advantage to use 'realloc()' instead of a
more flexible method (see below): You can make use of the size of
memory object known to the memory system. If you accept that you
"waste" the storage to remember the actual size of a memory object you
can do without 'renew' or 'realloc()' using a "traits" mechanism.

> I was thinking about the efficiency concerns here.  For what is
> conceptually a simple operation, three calls are made - a default
> ctor, a copy ctor and a dtor.  The copy ctor may potentially have to

Most likely, two operations are to be made: a placement call to the
ctor and a call to the dtor. It should be avoided to construct an
object twice (I'm not sure but I think constructing an object twice
results in undefined behavior)!

> allocate and deep-copy extensive data structures, so this can be very
> expensive, especially when shallow copy would be sufficient if the
> copy-ctor could KNOW that the source object was about to be destroyed.
> 
> So it seems to me that a combination of copy constructor and destructor
> could be used in these circumstances to "relocate" an object.  You
> could call this special member a "relocator".  This could offer
> substantial efficiency gains, especially in situations like
> vector<vector<A> >.

I agree with you that the copy constructor is sometimes a bad choice to
be used for doing a reallocation. A more appropriate constructor, a
"move constructor", can often be used: This constructor initializes one
object by moving all relevant members from one object into another one
leaving the original object in a state which is useless except for
destruction (this sometimes involves additional operations like setting
pointers to zero). This makes exactly use of the knowledge you want to
use for your "relocator" function. All what remains is to tell a
container class which does the actual relocation that it should use a
pair of "move constructor" and destructor calls. One possibility to do
so is to gather this information and other relevant information in a
"Traits" template argument to the container which contains 'static'
member functions to be used for certain operations.  Here are general
and specific "traits" which define a method for a movement:

  // The general 'move_traits' are useful for all classes defining
  // a copy constructor. Classes with other needs can define
  // specializations of this struct.

  template <class T>
  struct move_traits
  {
    T *move(T &source, void *target)
    {
      T *rc = new(target) T(source);
      source.~T();
      return rc;
    }
  };

  class Moveable
  {
  public:
    // pass a 'bool' for a different signature than the copy ctor
    Moveable(Moveable &, bool);
    // ...
  };

  struct move_traits<Moveable>
  {
    T *move(T &source, void *target)
    {
      T *rc = new(target) T(source, true);
      source.~T();
      return rc;
    }
  };

This solution of the move problem might require more work when
implementing a "moveable" class than the 'renew' approach. But is does
not require an extension of the language which is large enough without
'renew'. A problem might be that the STL containers do not use this
approach to move an object but I think this could be solved easily if
it is really desired. For an example of a container class (which is not
completely finished) using such an approach you can have a look at

  http://www.informatik.uni-konstanz.de/~kuehl/c++/array.h.html

Another approach is to use smart-pointers: Use a smart-pointer with
"move on copy" semantic (like 'auto_ptr'; is it defined like this in
the current version of the DWP?) or a "copy on write" semantic
involving some reference counting. Instead of copying the whole object,
a pointer to the object is copied. Unfortunately, the Standard Library
does not include a complete set of smart pointers. The only class of
this category is 'auto_ptr' with rather controversive semantics. This
is probably the reason why there are no other smart pointers included:
It is hard to find a reasonable consensus what they should do...

In general, I don't see why a 'renew' operator would be necessary.
Although it wouldn't cost anything for the portions of the code which
do not use it, it does not solve any problem which cannot be solved
with the current definition of the language.
-- 
dietmar.kuehl@uni-konstanz.de
http://www.informatik.uni-konstanz.de/~kuehl
I am a realistic optimist - that's why I appear to be slightly pessimistic
---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  Moderation policy:
  http://reality.sgi.com/employees/austern_mti/std-c++/policy.html. ]
Technical Details
Message-ID: <199602112213.XAA12589@uzwil>
Path: arc1-ca.pugleaf.net!in2.uu.net!bounce-back

Show Full Headers
Complete Article Headers
From: Dietmar Kuehl <Dietmar.Kuehl@uni-konstanz.de>
Message-ID: <199602112213.XAA12589@uzwil>
X-Original-Date: Sun, 11 Feb 1996 23:13:09 +0100 (MET)
Path: arc1-ca.pugleaf.net!in2.uu.net!bounce-back
Date: 12 Feb 96 07:17:28 GMT
Approved: fjh@cs.mu.oz.au
Organization: -
Subject: Re: proposal: renew & relocator member fn
Reply-To: Dietmar.Kuehl@uni-konstanz.de
Newsgroups: comp.std.c++
X-Mailer: ELM [version 2.4 PL25]
X-Auth: PGPMoose V1.1 PGP comp.std.c++
 iQBFAgUBMR7zmeEDnX0m9pzZAQGYnAF/djDtEyTa/8neazM0wpt9FcSbPYSBla6e
 xxPNd5Md0lKRSUHcYw/h+26zMkXWHyDW
 =5vRa