奇异模板加编译时自省加静态构造是成功,以自动序化,解序为例

原文地址
作者:h.s.teoh

最近,我需要扩展简单序化系统,来处理多态对象.
昨天,我发现个优秀解决方案:用crtp(奇异递归模板),来注入方法至继承类.

class Saveable(Derived, Base) : Base {
    static if (is(Base == Object)) {//基类
        // 顶级虚函数
        void save() { ... }
    } else {
        //继承类,盖
        override void save() { ... }
    }
}

class Base : Saveable!(Base, Object) { ...  }
class Derived1 : Saveable!(Derived1, Base) { ... }
class Derived2 : Saveable!(Derived1, Base) { ... }

奇异声明在类的第1行,很难丢失.可保存参数,使我们容易注入盖方法至类层次,并区别基类/继承类.
可保存保存方法,用模板参数来自省继承类并生成序化字段代码.在序化输出中它包含生成标识类型的标签的代码.从而完成了一半序化.
为了解序,可以用对象.工厂.但接口太旧,且从正确类型中读回字段有断开,因而可以用静态构造器来修复.

alias Loader = Object function(InputFile);
Loader[string] classLoaders;

class Saveable(Derived, Base) : Base {
    static if (is(Base == Object)) {//基类
        // 顶级虚函数
        void save() { ... }
    } else {
        //继承类,盖
        override void save() { ... }
    }
    static this()//静态构造器.
    {
        classLoaders[Derived.stringof] = (InputFile f) {
            auto result = new Derived;
            ... //用自省来读回继承的字段
            return result;
        };
    }
}

这儿神奇的地方是,每个可保存的实例生成一个静 本()块,有继承类的全部编译时信息.所以函数字面可用编译时自省来生成可序化代码.然后通过以类名作为来注册函数字面全局加载表.(为了简单,这里我用.的串,对大规模项目,你可用.的混杂).
因为,静 本块在启动程序,加载动态库时运行.确保启动程序类加载器有程序要用的所有信息.所以解序代码可简单在类加载器中查找保存的类型签.并调用函数指针重构对象.结果是,为可序化任何类,你只需要用:

class MyClass : Saveable!(MyClass, MyBase) { ... }

替换:

class MyClass : MyBase { ... }

其他所有全部自动搞好.不需要插件,重复序化类,运行时类型信息,甚至还支持动态库加载的类定义.只要你用Runtime.loadLibrary来确保运行静态构造器.因为静态构造器注入任何新类加载器至类加载器.并自动教会解序代码如何解序.
奇异模板+编译时自省+静态构造==成功!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值