Article View: comp.std.c++
Article #3220Re: Why no allocator-specific delete?
From: James Kanze US/ESC 60/3/141 #407...
Date: Sat, 03 Feb 1996 04:56
Date: Sat, 03 Feb 1996 04:56
133 lines
5569 bytes
5569 bytes
In article <4eqn5b$les@noc.tor.hookup.net> mtimmerm@microstar.com
(Matt Timmermans) writes:
|> (kanze@lts.sel.alcatel.de (James Kanze US/ESC 60/3/141 #40763))
|> | In article <4e85k6$b04@noc.tor.hookup.net> mtimmerm@microstar.com
|> | (Matt Timmermans) writes:
|> |
|> | | ... I can't, in fact, think of a single way that
|> | | placement-new could be used properly.
|> |
|> | [two decent uses described]
|> |
|> | | The lack of a placement-delete is on of the many factors in C++
|> | | conspiring to make it absolutely impossible to make generic
|> | | collections that hold actual objects (with constructors) instead
|> | | of just pointers.
|> | I don't understand the problem. My containers all contain actual
|> | objects, and not just pointers.
|> I spoke somewhat too generally. Let's say I want to make a generic list:
|> template <class T> class ListOf;
|> which stores acutal objects of type T (not just pointers) and contains
|> methods to add and delete items from the list. Lets say I also have a
|> class:
|> class A
|> {
|> ...
|> public:
|> A(int alpha,int beta);
|> ~A();
|> };
|> Note that class A has no valid copy semantics. How can I implement ListOf
|> such that ListOf<int> and ListOf<A> both work? There are lots of slimy
|> hacks, but no elegant solutions.
You must provide ListOf with some way of knowing how to construct an
object in the list. STL takes the simple approach: a copy constructor
will be used. My own container classes will use either a copy
constructor *or* the default constructor, according to the function
invoked. (In fact, not all of my container classes do this.) In both
cases, however, ListOf implicitly knows how to construct an object; if
what ListOf implicitly knows isn't true, you're out of luck.
The alternative would be to provide a constructor functional object as
parameter for all functions which might need to construct an object.
This is totally general, but may be a pain for users in the vaste
majority of cases where copying is the best solution.
Thus, in the list class itself:
template< class T >
class ListOf
{
public :
class ElemCtor
{
public :
virtual ~ElemCtor() {}
virtual void construct( T* rawMemory ) const = 0 ;
} ;
void insertAtHead( ElemCtor const& ctor ) ;
// ...
} ;
As a user, I might write:
void
insertIntoList( ListOf< A >& list , int alpha , int beta )
{
class C : public ListOf< A >::ElemCtor
{
public :
C( int a , int b )
: alpha( a )
, beta( b )
{}
virtual void construct( T* rawMemory ) const
{
new ( rawMemory ) A( alpha , beta ) ;
}
private :
int alpha ;
int beta ;
} ;
list.insertAtHead( C( alpha , beta ) ) ;
}
With member templates, this could be even easier, since you no longer
need the base class ListOf< T >::ElemCtor, and you could pass global
functions or functional objects indifferently. Even using the above
scheme, most of the derived classes can be simpler. Typically, you
might skip the constructor, make the data members public, declare a
named local instance of the class, and share the data members, thus:
void
insertIntoList( ListOf< A >& list , int alpha , int beta )
{
class C : public ListOf< A >::ElemCtor
{
public :
virtual void construct( T* rawMemory ) const
{
new ( rawMemory ) A( alpha , beta ) ;
}
int alpha ;
int beta ;
} c ;
c.alpha = alpha ;
c.beta = beta ;
list.insertAtHead( c ) ;
}
If the constructor arguments are not just the arguments of the
function, this is the classical way of simulating nested functions and
closure. A bit verbose, but still quite usable.
--
James Kanze Tel.: (+33) 88 14 49 00 email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs-Bourgeois, F-67000 Strasbourg, France
Conseils, itudes et rialisations en logiciel orienti objet --
-- A la recherche d'une activiti dans une region francophone
---
[ comp.std.c++ is moderated. Submission address: std-c++@ncar.ucar.edu.
Contact address: std-c++-request@ncar.ucar.edu. The moderation policy
is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Technical Details
Message-ID:
<9602021056.AA05851@lts.sel.alcatel.de>Path:
arc1-ca.pugleaf.net!cs.mu.OZ.AU!bounce-backReferences:
<4dvid8$460@news.bridge.net> <4e0u1s$5fv@engnews1.Eng.Sun.COM> <4e85k6$b04@noc.tor.hookup.net> <KANZE.96Jan29095513@slsvewt.lts.sel.alcatel.de> <4eqn5b$les@noc.tor.hookup.net>Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!cs.mu.OZ.AU!bounce-back From: James Kanze US/ESC 60/3/141 #40763 <kanze@lts.sel.alcatel.de> Newsgroups: comp.std.c++ Subject: Re: Why no allocator-specific delete? Date: 03 Feb 96 04:56:43 GMT Organization: - Approved: fjh@cs.mu.oz.au Message-ID: <9602021056.AA05851@lts.sel.alcatel.de> References: <4dvid8$460@news.bridge.net> <4e0u1s$5fv@engnews1.Eng.Sun.COM> <4e85k6$b04@noc.tor.hookup.net> <KANZE.96Jan29095513@slsvewt.lts.sel.alcatel.de> <4eqn5b$les@noc.tor.hookup.net> NNTP-Posting-Host: munta.cs.mu.oz.au X-Original-Date: Fri, 2 Feb 96 11:56:12 +0100 In-Reply-To: mtimmerm@microstar.com's message of 01 Feb 1996 09:26:44 PST X-Auth: PGPMoose V1.1 PGP comp.std.c++ iQBFAgUBMRLrOOEDnX0m9pzZAQFK6gF/R+VHDly6ZiRfqmQHiXTCuptA4bk8ykaa XDAz9p/mWySwKfcBFZ0BS/sKfe62aIUQ =9MGw Originator: fjh@munta.cs.mu.OZ.AU