C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

problem providing placement new in base class

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
Joseph Harvell
Guest





PostPosted: Tue Jul 12, 2005 8:36 am    Post subject: problem providing placement new in base class Reply with quote



I am trying to provide a base class to be used in a system where *most* of the memory allocation requires two parameters: a
memory handle and a memory type, with an options for pooled allocation and alignment. Accordingly, I defined the class
MyPlacementAllocator (class definition shown below).

The intended use of this class is that any non-abstract class that wants to use this allocation mechanism simply inherits
publicly from MyPlacementAllocator. This is working fine. But the problem I am having is that any class that has
MyPlacementAllocator as an ancestor cannot use any other signature for new.

I discovered this problem becuase I have a base class that is not abstract (MyExtendableConcreteClass). So I made it inherit
from MyPlacementAllocator so that anyone using an instance of this class can use the new operators I have provided *if they want
to*. Then I tried using the expression 'new MyExtendableConcreteClass()' and it failed because it could not find a matching
operator new.

Am I supposed to add 'inline static void *operator new(std::size_t size){return ::new MyExtendableConcreteClass();}' to the
class definition for MyExtendableConcreteClass? I don't think this is right because the latter new expression should result in
a call to the default constructor. I don't want to construct the object twice. I just want to be able to say 'Use ::operator
new(std::size_t) for any of the standard signature new expressions for MyExtendableConcreteClass and andy of its subclasses.'
Actually, if there is some syntax for this I would put it in MyPlacementAllocator instead: (e.g. 'inline static void *operator
new(std::size_t size){return ::new(size);}).

Another question. I used both 'inline' and 'static' for each operator new. I used static, becaue I think of new as being
static since there is clearly no object yet. However, this makes me wonder if it is overridable if I make it static. Does it
matter whether I say static or not? Also, I used 'inline' because the implementations of these are one line calls to other
functions. I figure that anyone who is newing up an object of a class must be able to see the definition of the class (and all
of its base classes). But I also want to make sure these can be overridden. It seems like the 'inline' would make that
impossible. But I think 'new' and 'delete' have special rules.

Another question: I haven't provided an equivalent signature for operator delete for each version of operator new. I can do
this I guess, but what happens if I don't? There is no syntax for me to actually invoke them. Everything compiles and runs so far.


class MyPlacementAllocator
{
public:
// marker type
struct PooledAllocation {};


// Non-pooled; throws exception
inline static
void *operator new(std::size_t size,
MemHandle memHdl,
int memType,
unsigned alignment=DEFAULT_ALIGNMENT) throw(std::bad_alloc);

// Pooled; throws exception
inline static
void *operator new(std::size_t size,
const PooledAllocation&,
MemHandle memHdl,
int memType,
unsigned alignment=DEFAULT_ALIGNMENT) throw(std::bad_alloc);

// Non-pooled, returns 0
inline static
void *operator new(std::size_t size,
const std::nothrow_t&,
MemHandle memHdl,
int memType,
unsigned alignment=DEFAULT_ALIGNMENT) throw();

// Pooled, returns 0
inline static
void *operator new(std::size_t size,
const PooledAllocation&,
const std::nothrow_t&,
MemHandle memHdl,
int memType,
unsigned alignment=DEFAULT_ALIGNMENT) throw();

inline static
void *operator new(std::size_t size);

inline static
void *operator new(std::size_t size,
const std::nothrow_t&);

// common delete for all
inline
void operator delete(void *mem,std::size_t size);

/*
virtual destructor is not necessary since delete does not use size parameter
*/
};

extern const MyPlacementAllocator::PooledAllocation Pooled;

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Gianluca Silvestri
Guest





PostPosted: Tue Jul 12, 2005 9:52 am    Post subject: Re: problem providing placement new in base class Reply with quote




"Joseph Harvell" <jharvell (AT) dogpad (DOT) net> ha scritto nel messaggio
news:btIAe.540$c41.467 (AT) newssvr30 (DOT) news.prodigy.com...
Quote:
I am trying to provide a base class to be used in a system where *most* of
the memory allocation requires two parameters: a
memory handle and a memory type, with an options for pooled allocation and
alignment. Accordingly, I defined the class
MyPlacementAllocator (class definition shown below).

The intended use of this class is that any non-abstract class that wants
to use this allocation mechanism simply inherits
publicly from MyPlacementAllocator. This is working fine. But the
problem I am having is that any class that has
MyPlacementAllocator as an ancestor cannot use any other signature for
new.

I discovered this problem becuase I have a base class that is not abstract
(MyExtendableConcreteClass). So I made it inherit
from MyPlacementAllocator so that anyone using an instance of this class
can use the new operators I have provided *if they want
to*. Then I tried using the expression 'new MyExtendableConcreteClass()'
and it failed because it could not find a matching
operator new.

Am I supposed to add 'inline static void *operator new(std::size_t
size){return ::new MyExtendableConcreteClass();}' to the
class definition for MyExtendableConcreteClass? I don't think this is
right because the latter new expression should result in
a call to the default constructor. I don't want to construct the object
twice. I just want to be able to say 'Use ::operator
new(std::size_t) for any of the standard signature new expressions for
MyExtendableConcreteClass and andy of its subclasses.'
Actually, if there is some syntax for this I would put it in
MyPlacementAllocator instead: (e.g. 'inline static void *operator
new(std::size_t size){return ::new(size);}).
you have to write void* operator new(std::size_t size) { return ::operator

new(size); }
Quote:

Another question. I used both 'inline' and 'static' for each operator
new. I used static, becaue I think of new as being
static since there is clearly no object yet. However, this makes me
wonder if it is overridable if I make it static. Does it
matter whether I say static or not? Also, I used 'inline' because the
implementations of these are one line calls to other


It doesn't matter if you use static or not. operator new and operator delete
are static by default when used in-class.

Quote:
functions. I figure that anyone who is newing up an object of a class
must be able to see the definition of the class (and all
of its base classes). But I also want to make sure these can be
overridden. It seems like the 'inline' would make that
impossible. But I think 'new' and 'delete' have special rules.
Inline if superflous when member functions are defined in-class

Another question: I haven't provided an equivalent signature for operator
delete for each version of operator new. I can do
this I guess, but what happens if I don't? There is no syntax for me to
actually invoke them. Everything compiles and runs so far.

It happens that the global deallocation function will be chosen, and from

then on all can happen.


Gianluca


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Thomas Richter
Guest





PostPosted: Tue Jul 12, 2005 4:20 pm    Post subject: Re: problem providing placement new in base class Reply with quote



Hi,

Quote:
I am trying to provide a base class to be used in a system where
*most* of the memory allocation requires two parameters: a memory
handle and a memory type, with an options for pooled allocation and
alignment. Accordingly, I defined the class MyPlacementAllocator
(class definition shown below).

The intended use of this class is that any non-abstract class that
wants to use this allocation mechanism simply inherits publicly from
MyPlacementAllocator. This is working fine. But the problem I am
having is that any class that has MyPlacementAllocator as an
ancestor cannot use any other signature for new.

Not unless you provide another one, that is.

Quote:
Am I supposed to add 'inline static void *operator new(std::size_t
size){return ::new MyExtendableConcreteClass();}' to the class
definition for MyExtendableConcreteClass?

Not in this form; the following would do: (But see CAVEATS below why
this compiles, but most likely does not work as you wish):

void *operator new(size_t s)
{
return ::operator new(s); // (1), see below
}

Quote:
Actually, if there is some syntax for this I would put
it in MyPlacementAllocator instead: (e.g. 'inline static void
*operator new(std::size_t size){return ::new(size);}).

See (1) above. But...

Quote:
Another question. I used both 'inline' and 'static' for each
operator new. I used static, becaue I think of new as being static
since there is clearly no object yet. However, this makes me wonder
if it is overridable if I make it static.

Of course. The two concepts are completely orthogonal.

Quote:
Does it matter whether I say static or not?

No. It's static in either case.

Quote:
Also, I used 'inline' because the implementations of these are one
line calls to other functions. I figure that anyone who is newing
up an object of a class must be able to see the definition of the
class (and all of its base classes).

"inline" never changes the semantics of the function. Thus, whether
you add it or not will make no difference on what the program does;
it might aid the compiler. But if you write the definition into the
class body anyhow, it is regarded as if "inline" would be written in
front of it.

Quote:
But I also want to make sure these can be overridden. It seems like
the 'inline' would make that impossible.

No.

Quote:
But I think 'new' and 'delete' have special rules.

Only concerning "static". They are always static, for reasons you
already gave.

Quote:
Another question: I haven't provided an equivalent signature for
operator delete for each version of operator new. I can do this I
guess, but what happens if I don't? There is no syntax for me to
actually invoke them. Everything compiles and runs so far.

And here comes the "CAVEAT". Unlike "common believe", the placement
operator delete *IS NOT* called for regular destruction of your
object. The code will call the regular delete operator, regardless of
how you allocated the object, i.e. regardless of what "operator new"
has been used to allocate it. The only case where "placement delete"[2]
is used where a new expression is used within the construction of
another object, and this construction fails, i.e. if

class FooBar {
//
MyCustomClass *mcc;
...
//
FooBar(...)
: mcc(new(memoryPool) MyCustomClass(...)), ....
{
...
// the code fails here, it calls operator delete(MemoryPool)
}
};

In *all other* cases, the regular operator delete will be called,
so it is up to you to find out the pool where the object was
taken from. This is also the reason why the naive approach (1) does
not work. The memory pool isn't stored.

Concerning the question of what happens if you forget to provide
a suitable "operator delete": Undefined, don't do that.

So long,
Thomas

[2] I call this "placement delete" and "placement new" even though you
need the argument for a memory pool, not for providing a place to
construct the object in. Thus, the name is here for "traditional
reasons". "new and delete with arguments" would be much better names.


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.