D语言:为什么构造函数不会被继承?

4
有没有一种方法,当参数完全相同时,不必重复写 this(parent class args) {super(parent class args);}
代码如下:
class Parent {
  string name;

  this(string name) {
    this.name = name;
  }
}

class Child : Parent {
}

unittest {
  auto child = new Child("a name");
  assert(child.name == "a name");
}

https://run.dlang.io/is/YnnezI

这个链接给我返回了编译错误:

Error: class onlineapp.Child cannot implicitly generate a default constructor when base class onlineapp.Parent is missing a default constructor
1个回答

10

Java和C#也没有继承构造函数(除非在最近几年有所改变 - 我认为C ++ 11之前也不允许),D遵循相同的原理,因此您可以通过查找与它们有关的内容来了解更多信息。

基本上,原因是子类必须具有自己独特的状态-至少是像vtable这样的东西,即使您没有声明任何自己的变量-因此需要一个唯一的构造函数。否则,您可能会有未初始化的成员。

如果继承一直进行下去,由于Object有this(),new AnyClass();将编译并导致大量无效对象。(在常规D中,如果声明带有参数的任何ctor,则会禁用自动生成的零参数。)

现在,理论上D可以像C ++一样自动生成其他args...只是它没有。可能主要是因为这是C ++中相对较新的想法,并且D的类系统主要基于Java的旧系统。

但是所有这些都说了,让我向您展示一个技巧:

this(Args...)(auto ref Args args) { super(args); }

把它放在你的子类里,你就可以一次性继承所有父类的构造函数。如果给定参数的super不能编译通过,那么这个也不行,所以它也不会添加随机的东西。如果需要,你还可以用更具体的版本重载它,因此它是一个合理的小替代内置语言功能。


感谢您的好解释。我主要来自JavaScript世界,那里的类构造函数是继承的。单行构造函数真的很不错,可以减少一些样板代码。 - tirithen
1
构造函数现在可以使用模板了?太好了,我错过了这个功能 :D - weltensturm
1
哦,是的,它们现在可能已经存在很长时间了! - Adam D. Ruppe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接