"Value class instance" pattern?
bearophile
bearophileHUGS at lycos.com
Sat Jul 13 05:47:27 PDT 2013
I don't know if this post is more fit for the main D newsgroup.
In the end I have decided that it's better to ask here first.
Here inside every instance of Bar there is a reference to an
instance of Foo:
abstract class Something {
int spam(int);
}
class Foo : Something {
int x;
this(int xx) { x = xx; }
override int spam(int x) { return x; }
}
class Bar : Something {
Foo f;
int y;
this(Foo ff) { f = ff; }
override int spam(int x) { return x; }
}
void main() {
auto b = new Bar(new Foo(1));
}
In C++ class instances are values, so the class Bar can contain
an instance of Foo as a value. This removes one allocation and
one indirection and decreases a bit the pressure on the GC. How
to do the same thing in D? Can I use Scoped or something to do
that?
This is one solution I have found, to create a FooValue struct,
and use Foo only as a wrapper:
abstract class Something {
int spam(int);
}
struct FooValue {
int x;
this(int xx) { x = xx; }
int spam(int x) { return x; }
}
class Foo : Something {
FooValue f1;
this(int xx) { f1.x = xx; }
override int spam(int x) {
return f1.spam(x);
}
}
class Bar : Something {
FooValue f2;
int y;
this(FooValue fv) { f2 = fv; }
override int spam(int x) { return x; }
}
void main() {
auto b = new Bar(FooValue(1));
}
But is this the best solution? (Beside containing some
boilerplate code, calling Foo.spam requires a function call and a
virtual call, instead of just a virtual call. Can we do with just
one virtual call?).
Recently Andrei has suggested to create a Phobos wrapper (not yet
implemented), I don't know if it's usable here:
http://d.puremagic.com/issues/show_bug.cgi?id=10404
If that wrapper will also allow derivation (as I have suggested)
then I think it will allow shorter code like this (but I think
this will keep needing a a function call and a virtual call to
call Foo.spam):
import std.typecons: Class;
abstract class Something {
int spam(int);
}
struct FooValue {
int x;
this(int xx) { x = xx; }
int spam(int x) { return x; }
}
alias Foo = Class!(FooValue, Something);
class Bar : Something {
FooValue f2;
int y;
this(FooValue fv) { f2 = fv; }
override int spam(int x) { return x; }
}
void main() {
auto b = new Bar(FooValue(1));
}
Bye and thank you,
bearophile
More information about the Digitalmars-d
mailing list