struct in class feature
js.mdnq
js_adddot+mdng at gmail.com
Sun Dec 9 12:05:00 PST 2012
stemming from:
http://forum.dlang.org/thread/azqevtjaoafbapiadgjz@forum.dlang.org
I believe the following idea would offer good benefit for
encapsulation in classes(increases the divide and conquer
approach):
For structs in classes(call them cstructs if you want):
prototype:
class A
{
cstruct B // Can only be used inside class A
{
int x;
void func()
{
// if func accesses any member of A then a hidden
"cthis" is passed to it to allow it to look them up
a = x*45;
}
}
B b;
int a;
}
A `cstruct` then, is useful for encapsulating data and
functionality in a class into smaller self-contained parts. It
would be very useful because it allows us to avoid collisions.
class A
{
cstruct B
{
opAssign;
}
opAssign;
}
even though, functionally both opAssigns accept the same this
pointer.
The reason being is that since a cstruct is fixed inside class
A(any value type of type cstruct has a fixed offset from the
start of class A), all the fields of both the class and struct
are calculated by simple offsets.
i.e., the struct this ptr is simply an offset from the class this
ptr. This allows us to use one or the other but we don't need to
store a ptr to a type A inside the struct to access is(and we can
also get at the private members of A).
Having such a feature makes it easy to wrap types in a struct and
provide custom operator overloading but still being able to
access the class members(which is not possible as it stands):
class A
{
cstruct sInfo
{
void print() { writeln(Name); }
}
string Name;
sInfo Info;
void print() { writeln("It's howdy doody time!"); }
}
This not also provides better encapsulation it also avoids
collisions. The above case is easily fixed but it is impossible
to do for build in overloads since we can't specify the type we
want to overload(it works on the class, not a member of a class):
e.g., the above can be written as
class A
{
string Name;
void printInfo() { writeln(Name); }
void print() { writeln("It's howdy doody time!"); }
}
If one wants(although, we lose the hierarchy potential).
But what about
class A
{
cstruct B
{
opAssign(int) { writeln("Inside " ~ Name); ... }
}
string Name;
B b;
opAssign
}
Both a and b have their own opAssigns, b's opAssign can access
A's members(without storing a ptr to an A). But we can't
"flatten" the hierarchy like the first case:
class A
{
string Name;
int b;
opAssign
opAssign(int) { writeln("Inside " ~ Name); ... } // works on
A, not int b!
}
One can say that all we need to do to get such functionality is
store a ptr of type A and set it in the structs. This is a huge
waste of memory though and not necessary since we can just pass a
"this"(cthis) ptr to the methods inside.
Obviously such structs can only be used in fields inside the
class, not arbitrarily, and so are not quite the same thing as
pass by value structs(which, when copied, would lose their
relationship to their parent class). We would not allow a struct
to be copied because then it would be disassociated from it's
container object which would invalidate cthis.
(although we could convert it to a normal struct, one that
doesn't use methods involving cthis and it should work just like
any other struct... or "lift" the structs to include a this ptr
inside that is used(but possibly create unintended consequences))
Any ideas if this is achievable or anything fundamentally wrong
with it? My purpose for it is to provide additional functionality
to fields inside classes but not have to include a this ptr in
them for no reason. It is achievable using offsets and pointers
but requires a lot of manual work that I feel the compiler could
do easily.
More information about the Digitalmars-d
mailing list