新特性:
1、給委托增加ptr屬性,指向委托所綁定的對象。
這是一個語法糖,dg.ptr被轉化為cast(void*)dg,它只能作右值,所以除了能讀取它以外,在語法上禁止對它賦值。要想把委托綁定到不同的對象,你只能自己實現:
class?Foo{
????int?foo;
public:
????this(int?foo){
????????this.foo?=?foo;
????}
????void?bar(){
????????writefln(foo);
????}
}
void?main(){
????alias?void?delegate()?DG;
????DG?dg?=?&(new?Foo(1)).bar;
????Foo[10]?foos;
????foreach(int?i,?inout?Foo?foo;?foos){
????????foo?=?new?Foo(i);
????}
????void**?ptr?=?cast(void**)&dg;
????foreach(Foo?foo;?foos){
????????*ptr?=?cast(void*)foo;
????????dg();
????}
}
這種方式也不是我們所希望的,一般來說委托綁定到多個對象時,因為是取到某成員函數指針,再進行綁定。比如模擬一個ActiveSupport所擴展的一個ruby.Array#map用法:
import?std.stdio;
class?Foo{
????int?foo;
public:
????this(int?foo){
????????this.foo?=?foo;
????}
????void?bar(){
????????writefln(foo);
????}
}
class?Array(T){
????private:
????T[]?data;
????public:
????this(T[]?data){
????????this.data?=?data[0?..?length];
????}
????void?map(void?function()?func){
????????void?delegate()?dg;
????????void**?funcPtr?=?cast(void**)&dg?+?1;
????????*funcPtr?=?func;
????????void?**?ptr?=?cast(void**)&dg;
????????foreach(T?v;?data){
????????????*ptr?=?cast(void*)v;
????????????dg();
????????}
????}
}
void?main(){
????auto?arr?=?new?Array!(Foo)([new?Foo(1),?new?Foo(2),?new?Foo(3)]);
????arr.map(&Foo.bar);
}
是的,delegate內部保存了2個指針,所以我們可以容易地hack它。
[注:上面的main函數中數組直接量賦給棧對象也是這個版本中新增的內容,顯然只能用于static對象是很雞肋的。這里簡單帶過不提。]
[注:上面這個map的模擬并不是ActiveSupport的map擴展的全部用途,那個map還是收集返回值,這里只演示調用語法。ActiveSupport中擴展的map調用語法是map(&:to_s),就可以收集到數組中所有元素調用to_s后的返回值。]
2、給內嵌內的實例增加outer屬性,指向外層對象。
import?std.stdio;
class?Outer{
????class?Inner{}
????this(){
????????Inner?inner?=?new?Inner;
????????inner.outer.foo();
????}
????void?foo(){
????????writefln("foo");
????}
}
void?main(){
????Outer?outer?=?new?Outer;
}
這個特性可能應用并不是很廣吧。
3、mixin多個析構函數。
template?A(){
????this(){
????}
????~this(){
????????writefln("A::~A()");
????}
}
template?B(){
????~this(){
????????writefln("B::~B()");
????}
}
class?C{
????mixin?A;
????mixin?B;
}
void?main(){
????C?c?=?new?C;
????delete?c;
}
這些析構函數會和mixin相反的順序執行。我不明白的是,為什么不讓mixin多個構造函數?為何不讓這些構造函數晚于被mixin的類(上面的C類)的構造函數,并按mixin進來的順序執行?