By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,407 Members | 920 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,407 IT Pros & Developers. It's quick & easy.

In-memory construction of variant types/subclasses?

P: n/a
Hi, slowly transitioning from C to C++, I decided to remodel a
struct/union (i.e. type identifier as first field, union of variant
types) as a class + subclasses. Switching functions are replaced by
virtual functions. So far so good.

Now what I used to do is have a struct, set its type and union member,
and return a pointer. I.e. I initialized the struct appropriately and
returned a reference. Now I'd like to do that in C++ (right now I
construct a new subclass with "new" and delete it after every call,
because the instance is only needed very shortly anyway; seems ugly to me).

I tried to define a union that contains all subclasses (that I will ever
use) of the base class, but C++ complains that it can't have objects
with constructors or destructors inside a union.

Is there any way to have a static piece of storage, and to return
references/objects(by value) or pointers to this piece of storage, while
also initializing it (i.e. myunion.objectB = ObjectB(); return
myunion.objecTB; or something like that)? In C I didn't need malloc()
in this case; I don't see why I should need new() now.
Jul 2 '06 #1
Share this Question
Share on Google+
9 Replies


P: n/a
Could you please give some supporting code?
I'm afraid I couldn't follow what you're saying (starting from
the 2nd paragraph), even though I read the thing at least 3
times ;-)

Ulrich Hobelmann wrote:
Hi, slowly transitioning from C to C++, I decided to remodel a
struct/union (i.e. type identifier as first field, union of variant
types) as a class + subclasses. Switching functions are replaced by
virtual functions. So far so good.

Now what I used to do is have a struct, set its type and union member,
and return a pointer. I.e. I initialized the struct appropriately and
returned a reference. Now I'd like to do that in C++ (right now I
construct a new subclass with "new" and delete it after every call,
because the instance is only needed very shortly anyway; seems ugly to me).

I tried to define a union that contains all subclasses (that I will ever
use) of the base class, but C++ complains that it can't have objects
with constructors or destructors inside a union.

Is there any way to have a static piece of storage, and to return
references/objects(by value) or pointers to this piece of storage, while
also initializing it (i.e. myunion.objectB = ObjectB(); return
myunion.objecTB; or something like that)? In C I didn't need malloc()
in this case; I don't see why I should need new() now.
Jul 2 '06 #2

P: n/a
In article <4g*************@individual.net>, u.*********@web.de
says...

[ ... ]
Is there any way to have a static piece of storage, and to return
references/objects(by value) or pointers to this piece of storage, while
also initializing it (i.e. myunion.objectB = ObjectB(); return
myunion.objecTB; or something like that)? In C I didn't need malloc()
in this case; I don't see why I should need new() now.
Yes -- it's called placement new. You do something like:

static char buffer[4096]; // assume that's big enough...

your_class *object = new(buffer) your_class;

When you're done with this object, you don't delete it -- instead,
you call its dtor directly:

object->~your_class();

As far as being anything like malloc goes: no, it's not. malloc does
one thing: allocates raw memory. The usual use of new does two
things: allocates some memory (about like malloc), and then creates
an object in that memory.

Placement new does only the _second_ part of that. It doesn't
allocate any memory -- it just creates an object in the memory you
designate. You're still creating a new object, so (at least to me) it
makes perfect sense to use the "new" keyword, even though you're not
doing anything that corresponds to what malloc does.

--
Later,
Jerry.

The universe is a figment of its own imagination.
Jul 2 '06 #3

P: n/a
Hi,

Yes, look up 'in place new' on parashift.

Here is a piece of my Variant type code:

// in the header
union {
Int8 Char;
Int64 Long;
UInt8 UChar;
UInt64 ULong;
double Double;
bool Bool;
char String [ sizeof( std::string ) ];
char Map [ sizeof( std::map<UVar*,UVar*, UFindVar) ];
char SRefPtr[ sizeof( MSRefPtr<ISerialize) ];
char WRefPtr[ sizeof( MWRefPtr<ISerialize) ];
char KeyStroke[ sizeof( MKey ) ];
};

And then in the implementation if the variant is for instance string: (from
a piece of the copy constructor passed variable Var)

case eString:
new( this->String ) string( *reinterpret_cast<string const *const>(
Var.String ) );
break;

--
Make sure to set the alignment options for your compiler otherwise maybe
stuff could get misaligned i.e. on char istead of four byte boundary.

Regards, Ron AF Greve

http://moonlit.xs4all.nl

"Ulrich Hobelmann" <u.*********@web.dewrote in message
news:4g*************@individual.net...
Hi, slowly transitioning from C to C++, I decided to remodel a
struct/union (i.e. type identifier as first field, union of variant types)
as a class + subclasses. Switching functions are replaced by virtual
functions. So far so good.

Now what I used to do is have a struct, set its type and union member, and
return a pointer. I.e. I initialized the struct appropriately and
returned a reference. Now I'd like to do that in C++ (right now I
construct a new subclass with "new" and delete it after every call,
because the instance is only needed very shortly anyway; seems ugly to
me).

I tried to define a union that contains all subclasses (that I will ever
use) of the base class, but C++ complains that it can't have objects with
constructors or destructors inside a union.

Is there any way to have a static piece of storage, and to return
references/objects(by value) or pointers to this piece of storage, while
also initializing it (i.e. myunion.objectB = ObjectB(); return
myunion.objecTB; or something like that)? In C I didn't need malloc() in
this case; I don't see why I should need new() now.

Jul 2 '06 #4

P: n/a
Jerry Coffin posted:

static char buffer[4096]; // assume that's big enough...

That's not guaranteed to be suitably aligned.

--

Frederick Gotham
Jul 2 '06 #5

P: n/a
st************@gmail.com wrote:
Could you please give some supporting code?
I have a function that will return one of many subclasses of a base
class (so it can't be call-by-value, because the subclasses can have
different sizes). I don't want to use new(), because the object is only
used for a very short time. In C I simply had a union of appropriate
types, initialized one of them, and returned a pointer. In C++ I'd like
to return a reference (ok, doesn't matter really), but the union can't
contain a list of my subclasses, due to init/destruction issues it seems.

Jerry and Moonlit, thanks for the pointers. I could use placement new
(though it remains open how best to declare the memory area; A union
would free me from the chore of having to determine how big my objects
actually are), but I was completely ignoring that objects could have
destructors (ok, these don't, but still the idea seems a bit ugly).

I guess I'll just continue to go with new/delete. The few cycles
shouldn't hurt.
Jul 2 '06 #6

P: n/a
Ulrich Hobelmann schrieb:
Hi, slowly transitioning from C to C++, I decided to remodel a
struct/union (i.e. type identifier as first field, union of variant
types) as a class + subclasses. Switching functions are replaced by
virtual functions. So far so good.
You could try the placement-new way, but others have done it before:

http://www.boost.org/doc/html/variant.html

Thomas
Jul 3 '06 #7

P: n/a
In article <%e*******************@news.indigo.ie>, fg*******@SPAM.com
says...
Jerry Coffin posted:

static char buffer[4096]; // assume that's big enough...

That's not guaranteed to be suitably aligned.
True -- a bit of ugliness to attempt to keep the code as simple as
possible, and concentrate on the placement new part. You're right,
however, that I probably should have pointed out the limitations more
thoroughly. OTOH, hopefully the comment was enough to indicate that
this buffer was really only for demo, not real use...

--
Later,
Jerry.

The universe is a figment of its own imagination.
Jul 3 '06 #8

P: n/a
Jerry Coffin posted:
In article <%e*******************@news.indigo.ie>, fg*******@SPAM.com
says...
>Jerry Coffin posted:

static char buffer[4096]; // assume that's big enough...

That's not guaranteed to be suitably aligned.

True -- a bit of ugliness to attempt to keep the code as simple as
possible, and concentrate on the placement new part. You're right,
however, that I probably should have pointed out the limitations more
thoroughly. OTOH, hopefully the comment was enough to indicate that
this buffer was really only for demo, not real use...

Yes I see what you're getting at, try to keep the example as simple as
possible.

I myself like to throw in a little comment, maybe at that point in the
code, or perhaps afterwards down before my signature, something like:

static char buffer[64]; /* Let's pretend it's suitably aligned */
It's good to be pedantic.

--

Frederick Gotham
Jul 3 '06 #9

P: n/a
Thomas J. Gritzan wrote:
Ulrich Hobelmann schrieb:
>Hi, slowly transitioning from C to C++, I decided to remodel a
struct/union (i.e. type identifier as first field, union of variant
types) as a class + subclasses. Switching functions are replaced by
virtual functions. So far so good.

You could try the placement-new way, but others have done it before:

http://www.boost.org/doc/html/variant.html
Thanks, but that feels a bit more heavyweight than I planned to use.
Jul 3 '06 #10

This discussion thread is closed

Replies have been disabled for this discussion.