我希望将此功能添加到某些类中.例如Widget类,它必须具有Container定义的相同功能.
我可以让Widget从Container继承.现在,Container被定义为具有this(),数据成员,成员函数,不变量和单元测试的类.容器包含一个容器数组,因此设计中有一个错误:如果Foobar还继承了Container并且我们将Foobar项添加到Widget的容器中怎么办?这一定是被禁止的.它们共享相同的基类,但它们具有不同目的的根本不同的东西……它们似乎只是共享一些功能.
将Container定义为接口是不可能的,因为它包含数据成员(并且不能解决问题).将Container定义为mixin,因为我们也有this()功能(或者这将如何解决?). mixin中函数的可见性属性也不起作用.另外,我无法传递Widget类的这个参数,因为它需要是平面数组的第一个元素.
我想给Container一个模板参数,告诉它它是什么容器:
abstract class Container(T) { ... T[] elements; } class Widget: Container!Widget { }
这给出了一个错误:类容器.__ unittest2.Widget基类由Container正向引用.
你会如何实现这个?我还可以在Container中添加检查,以确保在添加子项时,它与父项具有相同的类型.但我该如何检查呢?
abstract class Container { void add(Container child) { // pseudo-code assert (is(getFirstDerivedType(this) == getFirstDerivedType(child))); ... } ... Container[] elements; }
编辑:
即使第一段代码没有发出错误信号,它仍然无法真正解决问题.我不能随意添加更多功能,因为只允许一个基类.其他人需要是接口,这是根本不同的东西.接口确保派生类中存在某些功能,它们本身不添加功能.
这应该用(模板)mixins来解决.但是mixins不能向构造函数添加代码(只有在未定义时才替换),不能将代码添加到不变量(不定义多次定义),不能指定成员函数可见性或使用其他类/结构特定关键字…
我认为你这是错误的方式.您正试图从内部向各种类添加功能,而从外部添加它会更有意义,即扩展它们.容器应该包含Widget,而不是相反.然后,您可以使用别名将非容器调用转发到包含的Widget.
像这样的东西:
import std.stdio; class Container(T) { public: this(T elem) { m_this = elem; add(this); } void add(Container elem) { m_elems ~= elem; } alias m_this this; private: T m_this; Container m_elems[]; } class Widget { public: this(int x) { this.m_x = x; } int foo() { return m_x; } int m_x; } alias Container!Widget CWidget; void main() { CWidget w1 = new CWidget(new Widget(1)); CWidget w2 = new CWidget(new Widget(2)); w1.add(w2); writeln(w1.m_x); writeln(w1.foo()); }
注意你如何通过调用w1.m_x和w1.foo()仍然可以像使用Widget一样使用w1.