c++ 支持多继承,所以我觉得需要一个一个初始化还有情可原。本来多继承就已经搞得很复杂了,一口气直接初始化难度太高了。
delphi 里不光 constructor 里可以调用 virtual method,而且连 constructor 本身都可以是虚的。并且在官方 vcl 库里属于标准操作,我记得当年李维的书还专门给起了个名字,叫汉堡包什么的,大概类似这样:
TFoo = class(TComponent)
construcor Create(parent: TComponent); override;
...
end;
constructor TFoo.Create(parent: TComponent)
begin
Self.Foo := 123;
Self.Bar();
inherited Create(parent);
Self.Baz();
end
inherited 相当于 super。delphi 里创建新 object 的时候,在分配好内存后,编译器直接把所有的 vmt(virtual method table)指针都设好,不光是 class 本身,还包括全部的 interface 指针,然后才调用 constructor。现在已经记不清是不是每个 class 其实都是静态数据,只要直接把 pointer[-1] 直接指向 class 这一个操作就完成了。另外,由于有些类型是 auto reference count 和 copy-on-write 的设计,所以对象初始化是有清零操作的。再加上
TFoo = class
private
FBar: Integer;
// ...
end;
是不支持 FBar: Integer = 42 这种语法的,所以压根就不存在类似问题。就算支持我觉得也不是啥问题,哪怕调用 class virtual method 来初始化,无非也就是清零对象、设好指针后,增加一个 method,然后再调用 constructor 而已。顺便一提,delphi 里 class 本身也是 object,所以 class method 也都可以 virtual/override。所以当年在看到号称非常 oo 的 java 居然连这都不支持的时候,我也是非常震惊的。delphi 里
type
TComponentClass = class of TComponent;
var
fooClass: TComponentClass;
fooInsance: TComponent;
begin
fooClass := bar(); // TFoo
fooInstance := fooClass.Create(parent);
这种常规操作跑到 java 里就非得靠 design pattern 才能完成
【 在 DoorWay 的大作中提到: 】
: 这就跟 js 为啥要抄 java.util.Date 一样,你一个带 gc 的语言,又不支持多继承,为啥非要抄 c++ 的实现?
: —— 这里是说java抄cpp吗?
: 基类构造函数里调虚函数,cpp调不到虚的,理由是没完成子类构造。是cpp著名的坑,还专门有个 two-phrase creation的idiom。基类构造内无法访问子类成员。
: ...................
--
修改:eGust FROM 203.184.25.*
FROM 203.184.25.*