Having trouble with objects.

Jarrett Billingsley kb3ctd2 at yahoo.com
Tue Mar 18 06:05:19 PDT 2008


"Jarrod" <qwerty at ytre.wq> wrote in message 
news:frobsv$960$1 at digitalmars.com...
> Hey all.
> As I might have mentioned a while ago, I have a config library that I
> wrapped in D classes a while ago.
> While it works perfectly fine, it's currently running somewhat
> inefficiently and I wish to fix this.
>
> The problem: The library currently contains two classes. A root class and
> a node class. To load/create a config, one would create a root class and
> tie it to a file. Each key=value pair in the config can be accessed by
> passing the value's "path" to the root object, which will return a node.
> Herein lies the issue.
> Nodes are very short lived objects, and are often created and discarded
> very quickly. It would make far more sense if a node was a struct, as
> classes being uses like this tend to needlessly waste memory. The problem
> is I need to create the node in the root object (or in a parent node) and
> pass it back to the caller which would be more efficient to do with
> classes. In C++, what I would do is pass the back argument to the
> struct's constructor, which would create the struct and pass it back
> rather efficiently, and the node would be destroyed when scope is left. I
> doubt this is possible in D since structs don't have constructors.
> So what should I do?

NRVO (Named Return Value Optimization) to the rescue.  There are no struct 
constructors, but it doesn't mean the compiler can't optimize this out. 
When you return a struct from a function, chances are very good that it will 
not be pushed onto the stack, but will be constructed in place.  So even 
though it looks like you're allocating (on the stack) and filling out a 
struct in the function, the compiler will rewrite the function so that a 
pointer to the struct is passed as a parameter and the function fills out 
the struct in place.

> Another issue: Nodes can contain different data types. As such, I need to
> access their contents using an overloaded function 'getValue' which will
> use the passed parameter to determine what type of data the node holds
> and then pass it back. Yes, this sucks. Since DMD doesn't have implicit,
> multiple opCast overloads it appears that the only other solution is to
> have a different node type for each type of data. I guess this can be
> done with templates but nodes are created at runtime, not compile time.
> Different node types also mean I need to know what type of node the root
> config will return and I can't always do that since configs are user
> editable.
> Is there anything I can do about this?

Well, what would you have to do in C++?  So you have multiple implicit cast 
overloads, but how is the node represented?  As a tagged union?  As a string 
which is converted to the correct type upon use?  Is there a member in the 
node which represents its type?  Don't you still need to check that the node 
is of the correct type before getting its value anyway, by which time you 
already know the type and the implicit cast is next to useless?

It sounds like your node is wanting to be a variant.  In D1, there's a 
variant type in std.boxer called Box, and in D2, there's std.variant.  (In 
Tango, there's tango.core.Variant.)  Or, if you want to implement it 
yourself, it's not that hard, it's basically a tagged union with some 
methods to check the type and convert it to a desired value. 




More information about the Digitalmars-d-learn mailing list