Aggregates & associations
Bruce Adams
tortoise_74 at yeah.who.co.uk
Tue Dec 18 17:34:31 PST 2007
On Wed, 19 Dec 2007 00:53:43 -0000, Daniel Keep
<daniel.keep.lists at gmail.com> wrote:
>
> You seem to be getting confused as to how D classes work. In D, classes
> work like they do in Java: they are *always* references. That is,
>
> class Foo {}
> Foo a;
>
> Here, a is *effectively* a pointer; it is a reference to an instance of
> Foo, just like in Java.
>
Right. I got that.
> If you want to control the layout of memory, you can use a struct.
>
> struct Foo
> {
> int a, b;
> }
>
> struct Bar
> {
> Foo foo;
> float x;
> }
>
> Bar b;
>
> Here, b is exactly 12 bytes long. &b.foo.a == &b.foo == &b. If b is
> declared as a function local, it takes up 12 bytes on the stack; if it's
> declared as part of an aggregate type (like a struct, class or union,)
> then it takes up 12 bytes within an instance of that type.
>
> So, to get back to your original question, you could probably represent
> aggregates as structs and associations with classes. Note that the only
> one that can represent *both* would be a struct:
>
> struct Baz
> {
> Foo aggregate;
> Foo* association;
> }
>
> Currently, this is all a bit of a mess.
Yes it is isn't it.
Why on Earth would any sensible refactoring of C++ include making the same
declaration "Foo aggregate" context dependent on whether its inside a
struct or a class.
Why did Walter do this when his other refactorings were so sane?
(Lose two guru points and make a sanity roll)
This is not want I would want as classes and structs are different things.
An instance of
a class ISA object. A instance of a struct is not an object.
This is also no good because structs have value semantics and classes have
reference
semantics. Is this why we I see a "ref" keyword popping up occasionally?
Is it the main
way of making a struct behave like a class?
Is this all for the sake of eliminating -> and &? I'm not sure it was
worth it.
I can see there is a trade off between:
Foo foo = new foo;
versus
Foo& foo = new Foo; //this is not D but it could have been
The reference form is the most common usage so you don't want to type the
extra &.
This makes sense with:
scope Foo foo;
being on (e.g.) the stack.
Though it doesn't obviously mean "I am a value type".
> However, I believe that Walter
> intends to (eventually) introduce scoped class members like so:
>
> class Foo {}
>
> class Bar
> {
> scope Foo aggregate;
> Foo association;
> }
>
> So that when an instance of Bar is destroyed, its 'aggregate' member is
> also destroyed (currently, this is impossible to guarantee if
> 'aggregate' is GC-allocated.)
>
> But that's not really useful at this point.
>
This is useful for defining ownership though it a stretch for the
definition of scope.
I suppose its better than introducing a new keyword like 'owned' though.
> Hope that helps.
>
> -- Daniel
It does but it makes me want to run away from D.
What is really needed is a sensible way of saying "this is a value" versus
"this is a reference" as a qualifier on the type.
In c++ value was the norm and reference was &. So if reference is the norm
we need
a qualifier that says I am a value.
Its not obvious what the best choice would be. Perhaps * because it is
conventionally
understood to C/C++ emigrees to mean dereference. So.
class Bar
{
*Foo aggregateValue;
Foo association;
}
I think the above syntax is particularly vile and would go for something
like "val" as the antinym of "ref".
i.e.
class Bar
{
val Foo aggregateValue;
Foo association;
}
The same keyword could solve the pass by value problem on functions too.
I like this it means that for every type there is always either a ref or
val qualifier. The ref qualifier
is just hidden because its the default.
Have I missed anything?
--
Using Opera's revolutionary [NOT!] e-mail client:
http://www.opera.com/mail/
More information about the Digitalmars-d
mailing list