2010-06-17 53 views
1

我读过的(在我们的例子_c1)初始化继承成员,而不是内源性的构造函数:初始化基类构造函数中的继承成员如何减少对...的调用?

class A 
{ 
    public int _c; 
} 

class B:A 
{ 
    public B(int c) 
    { 
     _c = c; 
    } 
} 

我们应该对它们进行初始化基类的构造函数内,因为这样的话,我们减少继承成员的电话(_c ):

class A 
{ 
    public A(int c) 
    { 
     _c = c; 
    } 
    public int _c; 
} 

class B:A 
{ 
    public B(int c) 
     : base(c) 
    { 


    } 
} 

如果_c字段基构造内部初始化,初始化的顺序如下:

1)首先衍生B类的字段初始被称为
2)然后基类A的字段初始化被称为(此时_c的值被设为0
3)B’s构造函数被调用,这又呼叫A’s定制构造
4)_c字段获取设置为一旦A’s定制构造函数返回一个参数c(内侧A’s定制构造的值)
5),B’s构造函数执行它的代码。

如果_c字段内B's构造初始化,初始化的顺序如下:

1)首先领域派生B类的初始化被称为
2)然后,基类A的字段初始化被称为(此时_c的值被设为0
3)B’s构造函数被调用,后者又调用A’s默认的构造
4)一旦A’s定制协nstructor回报,B’s构造函数设置_c场参数c

的价值至于我可以告诉大家,在这两种情况下被_c调用两次,所以我们是如何准确地减少对继承成员_c电话?

感谢名单

+0

当你有几个派生类时会发生什么?派生类的派生类? – Oded 2010-06-17 19:47:50

+0

我不确定我是否理解您要说的内容 – flockofcode 2010-06-17 22:22:10

回答

5

问题从这里开始:

public int _c; 

领域不应该是公开的,所以要做到这一点正确你将有一个属性,因此,你必须调用set访问。我想他们是刻意突出的区别是:

private int c; 
public int C {get {return c;} set {this.c=value;} } // ld, ld, st 
public Foo(int c) {this.c = c;} // ld, ld, st 
... 
Foo foo = new Foo(blah); // ld, newobj, st 

(这确实一个字段赋值构造)

VS

private int c; 
public int C {get {return c;} set {this.c=value} } // ld, ld, st 
public Foo() {} 
... 
Foo foo = new Foo(); // newobj, st 
foo.C = blah; // ld, ld, callvirt 

但是!这是所有的微型优化。通常,微不足道的get/set访问器将被内联 - 所以在现实中几乎没有什么区别。我会高兴地拥有:

public int C {get;set;} 
+0

我不喜欢那些“字段不应该公开”的总括声明。否则,这是一个很好的答案。 – 2010-06-17 19:59:29

+0

JS Bangs - ok;但公共领域应该是一个好的,理解充分的理由。不只是保存几个字符。没有*很多*这样的原因... – 2010-06-17 20:42:09

+0

我很抱歉,但我无法弄清楚你的回答如何回答我的问题。无论如何,如果您误解了我的问题,请点击以下链接指向作者提出这些声明的页面:“http://books.google.com/books?id=VGT1_UJzjM0C&lpg=PP1&dq=pro%20c%23%202008&pg=PA193# v = onepage&q&f = false“BTW - ld,ld和st缩写词代表什么? – flockofcode 2010-06-17 22:20:24

1

通常你会写C类这样的:

class A 
{ 
    public A(int c) : _c(c) 
    { 
    } 
    public int _c; 
} 

现在_c只能设置一次。

虽然在实践中我认为编译器会优化这一点,而您的最后一个例子将会像这个一样快。

+0

您确定这是正确的代码吗?我已经试过了,编译器报告了一个错误 – flockofcode 2010-06-17 22:18:49

相关问题