分配参数列表和初始化器列表中的值之间的区别 [英] Difference between assigning the values in parameter list and initializer list

查看:45
本文介绍了分配参数列表和初始化器列表中的值之间的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

class A {
  A(int value);
}

class B extends A{
  final int foo;

  B.one(this.foo) : super(foo); // Works

  B.two(int foo) : foo = foo, super(this.foo); // Doesn't work
}

B.one 中,我可以轻松地将 foo 的值传递给 super ,但是在 B.two 中>,我做不到.在这两种情况下,都在调用 super 之前分配了 foo 字段,在一种情况下它起作用,而在另一种情况下则失败.因此,问题在于在构造函数中创建字段的时间点.

In B.one, I can easily pass the value of foo to super but in B.two, I can't do that. In both cases, the field foo is assigned before calling super, in one case it works and in another it fails. So, the question is at what point the fields are created in the constructor.

推荐答案

Dart分为两个阶段构造对象:第一个由外而内,然后由内而外.

Dart constructs objects in two phases: the first outside-in and then inside-out.

初始化程序列表是从外到内执行的(从派生类到基类).完成此操作后,应初始化对象的成员,将对象视为已构造",并且 this 存在.(这就是为什么您不能在初始化列表中以有意义的方式使用 this 的原因;它尚不存在.)(从技术上讲,直接成员初始化发生在初始化列表之前,但我将它们合并在一起为简单起见.)

Initializer lists are executed outside-in (from derived class to base class). After this is done, the object's members should be initialized, the object is considered to be "constructed", and this exists. (That's why you can't use this in a meaningful way in an initializer list; it doesn't exist yet.) (Technically direct member initialization occurs before initializer lists, but I'm lumping them together for simplicity.)

然后从内到外(从基类到派生类)执行构造函数主体.

Constructor bodies are then executed inside-out (from base class to derived class).

此方法保证在执行基类构造函数主体时初始化对象的成员,从而允许在构造函数中进行虚拟调度.(相比之下,C ++纯粹由内而外构造对象,并不允许在构造函数和析构函数中进行虚拟派发.或者与Java相反,IIRC中,该类主要定义了自己的构造顺序,并且这些类负责确保执行任何虚函数调用构造函数是安全的.)

This approach guarantees that the object's members are initialized when the base class constructor body executes, allowing virtual dispatch to occur in the constructor. (In contrast, C++ constructs objects purely inside-out and disallows virtual dispatch in constructors and destructors. Or contrast to Java where, IIRC, the class mostly defines its own construction order, and the classes are responsible to ensure that any virtual function calls performed by the constructor are safe.)

没有这种方法,Dart构造函数主体要么不能保证执行虚拟函数时的安全性(Java方法),要么必须禁止虚拟调度(C ++方法).

Without this approach, a Dart constructor body either cannot guarantee safety when executing virtual functions (the Java approach) or must disallow virtual dispatch (the C++ approach).

另请参见:构造函数中的虚函数,为什么语言有所不同?

这篇关于分配参数列表和初始化器列表中的值之间的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆