在以下代码示例中,milk
由构造函数初始化,而egg
则不是。milk.spill()
。 egg.crack()
不会发生段错误,但import std.stdio;
void main() {
auto k = new Kitchen();
k.pollute();
}
class Kitchen {
Milk milk;
Egg egg = new Egg();
this() {
milk = new Milk();
}
void pollute() {
writeln("spilling milk");
milk.spill();
writeln("cracking egg");
egg.crack();
}
}
class Milk {
bool spilt = false;
void spill() { spilt = true; }
}
class Egg {
bool cracked = false;
void crack() { cracked = true; }
}
会发生。初始化实例变量的两种方法有什么区别?为什么前者正确而后者导致段错误?
'language' => 'de',
'components' => [
'i18n' => [
'translations' => [
'app*' => [
'class' => 'yii\i18n\PhpMessageSource',
'basePath' => '@app/messages',
'sourceLanguage' => 'en',
'fileMap' => [
'app' => 'app.php',
'app/error' => 'error.php',`
.....
答案 0 :(得分:5)
因此两种方式之间的区别在于代码运行时。在构造函数中初始化时,代码在运行时运行,此时每个新对象都会生成。当你直接在类成员上执行它时,该对象实际上是在编译时构造的并且是静态引用的。
在您的示例中,这意味着为每个Kitchen对象创建了一个新的Milk对象。当您运行new Kitchen
时,构造函数会运行,这意味着您也会获得new Milk
。
Egg
不同。它位于静态上下文中,因此初始化程序在编译时运行 - 只运行一次。这意味着在所有Egg
之间只共享一个 new Kitchen
。变量本身不是静态的,如果你在制作new Egg
后的某个时间将它分配给new Kitchen
,它只会影响厨房的那个实例,但它会立即引用它的对象是
因此,如果您只是将其设置为构造函数外的new Egg
并且永远不会替换它,那么您对该鸡蛋所做的任何修改都将在厨房的所有实例中可见 - 在您破解鸡蛋之后,再进行另一次{ {1}},它已经有一个破裂的蛋!