2010-06-17 56 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

相關問題