2010-06-17 6 views
1

J'ai lu que, au lieu d'initialisation membres hérités (_c1 dans notre exemple) constructeur intérieur dérivé:Comment l'initialisation des membres hérités dans le constructeur de la classe de base réduit les appels à ...?

class A 
{ 
    public int _c; 
} 

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

nous devrions les initialiser dans le constructeur de classe de base, car de cette façon, nous réduisons les appels aux membres hérités (_c):

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

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


    } 
} 

Si _c champ est initialisé à l'intérieur de constructeur de base, l'ordre d'initialisation est la suivante:

1) Tout d'abord le champ initializers de classe dérivée B sont appelés
2) Ensuite, initializers de champ de classe de base A sont appelés (à ce point _c est réglé sur la valeur 0)
3) B’s constructeur est appelé, qui appelle à son tour A’s constructeur personnalisé
4) champ _c se prépare à la valeur d'un paramètre c (à l'intérieur A’s constructeur personnalisé)
5) une fois que les retours du constructeur A’s personnalisés, constructeur B’s exécute son code.

Si _c champ est initialisé dans le constructeur B's, l'ordre d'initialisation est la suivante:

1) Tout d'abord le champ initialiseurs d'une classe dérivée B sont appelés
2), puis de Initialiseur sur le terrain d'une classe de base A sont appelés (à ce point _c est réglé sur la valeur 0)
3) constructeur B’s est appelé, qui appelle à son tour A’s constructeur par défaut
4) Une fois A’s co personnalisé nstructor retours, constructeur B’s met champ _c à une valeur du paramètre c

Pour autant que je peux dire, dans les deux cas a été _c appelé deux fois, alors comment exactement avons-nous réduit les appels à membre hérité _c?

Thanx

+0

Que se passe-t-il lorsque vous avez plusieurs classes dérivées? Ou des classes dérivées des classes dérivées? – Oded

+0

Je ne suis pas sûr de comprendre ce que vous essayez de dire – flockofcode

Répondre

5

Le problème commence ici:

public int _c; 

Les champs ne doivent pas être publiques, afin de le faire correctement vous auriez une propriété, et vous auriez donc appeler l'accesseur set.Je pense que ce qu'ils essaient de mettre en évidence est la différence entre:

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 

(qui fait une mission sur le terrain à l'intérieur le constructeur)

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 

Cependant! Tout est micro-optimisation. Souvent, les accesseurs get/set triviaux seront intégrés - il y a donc très peu de différence dans la réalité. Je voudrais bien avoir juste:

public int C {get;set;} 
+0

Je n'aime pas l'affirmation générale selon laquelle "les champs ne devraient pas être publics". Sinon, c'est une bonne réponse. –

+0

JS Bangs - ok; mais les terrains publics devraient être pour une bonne raison bien comprise. Pas seulement pour sauver quelques caractères. Il n'y a pas * beaucoup * de telles raisons ... –

+0

Je suis désolé, mais je n'arrive pas à comprendre comment votre réponse répond à ma question. De toute façon, au cas où vous avez mal compris ma question, voici le lien vers la page où l'auteur a fait ces revendications: "http://books.google.com/books?id=VGT1_UJzjM0C&lpg=PP1&dq=pro%20c%23%202008&pg=PA193# v = onepage & q & f = false "BTW - que signifient les abréviations ld, ld, st? – flockofcode

1

Normalement, vous devriez écrire classe C comme ceci:

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

Et maintenant _c est seulement défini précédemment. En pratique, je pense que les compilateurs optimisent cela, et votre dernier exemple sera aussi rapide que celui-ci.

+0

Etes-vous sûr que c'est le bon code? Je l'ai essayé et le compilateur signale une erreur – flockofcode

Questions connexes