placement new , is this acceptable?

L

lallous

class MyClass
{
static void *Allocate(int size);
static void Free(void *mem);
static MyClass *CreateInstance();
void DestroyInstance();
};

MyClass *MyClass::CreateInstance()
{
void * p = Allocate(sizeof(MyClass));

return new (p) MyClass;
}

void MyClass::DestroyInstance()
{
MyClass *i = this;
i->~MyClass();
Free(i);
}
 
J

Jonathan Turkanis

lallous said:
class MyClass
{
static void *Allocate(int size);
static void Free(void *mem);
static MyClass *CreateInstance();
void DestroyInstance();
};

MyClass *MyClass::CreateInstance()
{
void * p = Allocate(sizeof(MyClass));

what if p == 0?
return new (p) MyClass;
}

void MyClass::DestroyInstance()
{
MyClass *i = this;
i->~MyClass();
Free(i);
}

Who calls CreateInstace and DestroyInstance? Both are private.

This can be made to work, but why? The standard way to provide custom
allocation facilities for a class is to provide custom member
operators new and delete. Using a factory function instead of a public
constructor is appropriate sometimes, but is usually independent of
the decision to provide custom allocation. Also, why make the
constructor private?

Jonathan
 
L

lallous

Jonathan Turkanis said:
what if p == 0?


Who calls CreateInstace and DestroyInstance? Both are private.

This can be made to work, but why? The standard way to provide custom
allocation facilities for a class is to provide custom member
operators new and delete. Using a factory function instead of a public
constructor is appropriate sometimes, but is usually independent of
the decision to provide custom allocation. Also, why make the
constructor private?

Jonathan
Hello

Consider all method public, and an instance is created as:

MyClass *a = MyClass::CreateInstance();
a->DestroyInstance();

What is a factory function? can you provide links?
 
C

Claudio Puviani

lallous said:
class MyClass
{
static void *Allocate(int size);
static void Free(void *mem);
static MyClass *CreateInstance();
void DestroyInstance();
};

MyClass *MyClass::CreateInstance()
{
void * p = Allocate(sizeof(MyClass));

return new (p) MyClass;
}

void MyClass::DestroyInstance()
{
MyClass *i = this;
i->~MyClass();
Free(i);
}

Aside from the fact that this is an overly convoluted way to do things, your
approach doesn't support inheritance. How do you allocate/deallocate an instance
of a class derived from MyClass?

Claudio Puviani
 
L

lallous

Claudio Puviani said:
Aside from the fact that this is an overly convoluted way to do things, your
approach doesn't support inheritance. How do you allocate/deallocate an instance
of a class derived from MyClass?

Claudio Puviani

My question is whether the method used to create/destroy an instance is
acceptable?

For this design, no inheritance is planned.
 
P

puppet_sock

lallous said:
What is a factory function? can you provide links?

A factory function is exactly the kind of function you had
in your example, one that returns a pointer to a brand new
instance of the class. It gets its name because it is often
used in a thing called a factory. The idea is, you put some
overhead into each of several classes, then register those
classes with the factory. Then when you want an instance
of that class, you can request one from the factory. There
are many variations on this: For example all the entries
could be in a single inheritance heirarchy so that they
all come back as instances of the base type. Or you may
need to provide the factory with an initial instance of
each registered class. Or you may register the class along
with the name to be used to request new instances. Or a
factory may be used to create a set of instances of a class,
and thus not reallocate the memory, but only recycle it.
Lots of fun.
Socks
 
C

Claudio Puviani

lallous said:
Claudio Puviani said:
Aside from the fact that this is an overly convoluted way to do things,
[...]

My question is whether the method used to create/destroy an instance is
acceptable?

What part of "overly convoluted" doesn't answer your question? I suppose one
could get philosophical and ask "acceptable by who's standard?", but in
realistic terms, no, it's not acceptable. There are no benefits whatsoever to
your approach, but plenty of limitations. It probably served its purpose in
giving you a working example of placement new and calling destructors directly,
but I seriously recommend never doing that in real code.

For some proper ways to construct object factories, I recommend Alexandrescu's
book (which someone may have already done):
http://search.barnesandnoble.com/textbooks/booksearch/isbnInquiry.asp?isbn=0201704315&TXT=Y&itm=1

Claudio Puviani
 
L

lallous

Claudio Puviani said:
lallous said:
Claudio Puviani said:
Aside from the fact that this is an overly convoluted way to do things,
[...]

My question is whether the method used to create/destroy an instance is
acceptable?

What part of "overly convoluted" doesn't answer your question? I suppose one
could get philosophical and ask "acceptable by who's standard?", but in

Is the usage of placement new and calling the destructor like that a correct
one C++ syntax wise?

I heard there is "overhead" or extra bytes that needs to be allocated in
addition to the size of the class?

[snip ...book recomendation...]
 
C

Claudio Puviani

lallous said:
Is the usage of placement new and calling the destructor like that a correct
one C++ syntax wise?

Syntactically, it works, though your compiler could have told you that much.
I heard there is "overhead" or extra bytes that needs to be allocated in
addition to the size of the class?

You get overhead -- and typically much more than just one byte -- any time you
allocate using new or one of the malloc functions. Some replacement libraries,
like Hoard or SmartHeap, reduce this, there's always some amount of overhead.
You normally shouldn't have to worry about this, but if you ever have to
allocate tens or hundreds of thousands of objects, you might want to consider
specialized allocators.

Claudio Puviani
 
S

Steve Dubak

Claudio said:
Syntactically, it works, though your compiler could have told you that much.




You get overhead -- and typically much more than just one byte -- any time you
allocate using new or one of the malloc functions. Some replacement libraries,
like Hoard or SmartHeap, reduce this, there's always some amount of overhead.
You normally shouldn't have to worry about this, but if you ever have to
allocate tens or hundreds of thousands of objects, you might want to consider
specialized allocators.


Some specialized allocators utilize more memory overhead than others,
so if you're allocating many small objects, watch your memory
consumption. Hoard is pretty good with memory, much better than
smartheap. But alas, you pay for that memory conservation in speed.
Smartheap is much faster than hoard. And ESA from cherrystone software
labs is much faster than smartheap while using less memory than
smartheap. So if you're going to pick a specialized allocator, choose
carefully, benchmark, and watch the memory consumption.

Claudio Puviani



Steve Dubak
(e-mail address removed)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,479
Members
44,899
Latest member
RodneyMcAu

Latest Threads

Top