我编写了一个名为Container的类,它处理层次结构(对类用户可见),并将它们内部转换为平面数组。所以对于Container的外部来说,它看起来像Containers的层次结构,每个都有父节点和子节点。D以非耦合的方式向类中添加功能
这个功能我想添加到某些类。例如Widget类,它必须具有由Container定义的相同功能。
我可以让Widget继承Container。容器现在被定义为一个具有this(),数据成员,成员函数,不变式和unittests的类。 Container包含一个Containers数组,因此设计中有一个错误:如果Foobar也继承Container并且我们将Foobar项添加到Widget的容器?这一定是被禁止的。它们确实共享相同的基类,但它们具有根本不同的目的......它们似乎共享一些功能。
将Container定义为接口是不可能的,因为它包含数据成员(并且不能解决问题)。既然我们也有这个()函数(或者如何解决这个问题?),所以既没有将容器定义为mixin也没有。 mixin中的函数的可见性属性也不起作用。另外,我不能通过Widget类的this
参数,因为它需要是平面数组的第一个元素。
我想过放弃集装箱一个模板参数,告诉它这是什么样的容器:
abstract class Container(T)
{
...
T[] elements;
}
class Widget: Container!Widget
{
}
这给出了一个错误:类容器.__ unittest2.Widget基类向前集装箱引用。
你将如何实现这一点?我还可以在Container中添加检查,以确保在添加子项时,它具有与父项相同的类型。但我该如何检查?
abstract class Container
{
void add(Container child)
{
// pseudo-code
assert (is(getFirstDerivedType(this) == getFirstDerivedType(child)));
...
}
...
Container[] elements;
}
编辑: 即使代码的第一块不发出错误信号,它仍然没有真正解决问题。由于只允许一个基类,因此我不能随意添加更多功能。其他人需要成为接口,这是根本不同的东西。接口确保派生类中具有某些功能,但它们本身不添加功能。
这应该是用(模板)mixin来解决的。但mixin不能将代码添加到构造函数中(只有在未定义时才进行替换),不能将代码添加到不变量(定义多次不变),不能指定成员函数可见性或使用其他类/结构特定关键字...
我没有收到错误:class container .__ unittest2.Widget base ...'。谨慎分享更多? – Arlen 2012-01-02 01:25:57
这很奇怪。我无法在更简单的环境中重现这一点。我想这是一个编译器错误,因为如果我将Widget定义放在unittest中,它会发出错误信号。否则它不会......但现在我得到了“断言失败:'文件'template.c'中的行4893上的'global.errors';异常程序终止”而不是... – 2012-01-02 10:24:59
您可以使用多个子类型:add 'Container'作为'Widget'的子类型? (我不是专家:我刚刚在D书中几天前阅读过这方面的技术,看起来与你的问题有关。) – Xophmeister 2012-01-04 16:38:52