class A{
private :
B b;
public :
A(B &bb):b(bb){ maMethode(); }
private :
virtual void maMethode()=0;
}
class AA:public A{
public :
AA(B &bb):A(bb){}
// avec une définition correcte de maMethode()
}
Ce qui ne marche pas parce que le linker semble chercher
A::maMethode()...
Suis-je condamné à descendre l'appel à maMethode dans le corps du
constructeur de AA et des autres classes filles ? Une autre idée ?
class A{
private :
B b;
public :
A(B &bb):b(bb){ maMethode(); }
private :
virtual void maMethode()=0;
}
class AA:public A{
public :
AA(B &bb):A(bb){}
// avec une définition correcte de maMethode()
}
Ce qui ne marche pas parce que le linker semble chercher
A::maMethode()...
Suis-je condamné à descendre l'appel à maMethode dans le corps du
constructeur de AA et des autres classes filles ? Une autre idée ?
class A{
private :
B b;
public :
A(B &bb):b(bb){ maMethode(); }
private :
virtual void maMethode()=0;
}
class AA:public A{
public :
AA(B &bb):A(bb){}
// avec une définition correcte de maMethode()
}
Ce qui ne marche pas parce que le linker semble chercher
A::maMethode()...
Suis-je condamné à descendre l'appel à maMethode dans le corps du
constructeur de AA et des autres classes filles ? Une autre idée ?
meow wrote:class A{
private :
B b;
public :
A(B &bb):b(bb){ maMethode(); }
private :
virtual void maMethode()=0;
}
class AA:public A{
public :
AA(B &bb):A(bb){}
// avec une définition correcte de maMethode()
}
Ce qui ne marche pas parce que le linker semble chercher
A::maMethode()...
Oui. Il n'y a pas d'appel virtuel possible dans un
constructeur.
Dans le cas ci-contre, lorsqu'on construit un AA, on commence
par construire un A. Donc, lorsque le constructeur de A est
appelé, il ne sait pas que l'objet est un AA.
Il sait juste que c'est un A et ne peut donc faire de
résolution dynamique à ce moment là.
Vu autrement, lorsqu'un A est construit, il l'est avec une
vtable de A. Il n'a donc pas accès à la vtable de AA qui ne
sera « construite » que lors de la construction du AA (et
donc, une fois le A déjà construit).
Suis-je condamné à descendre l'appel à maMethode dans le
corps du constructeur de AA et des autres classes filles ?
Une autre idée ?
Oui. À moins, par exemple, de passer par une factory amie qui
appellerait maMethode() juste après la construction.
meow wrote:
class A{
private :
B b;
public :
A(B &bb):b(bb){ maMethode(); }
private :
virtual void maMethode()=0;
}
class AA:public A{
public :
AA(B &bb):A(bb){}
// avec une définition correcte de maMethode()
}
Ce qui ne marche pas parce que le linker semble chercher
A::maMethode()...
Oui. Il n'y a pas d'appel virtuel possible dans un
constructeur.
Dans le cas ci-contre, lorsqu'on construit un AA, on commence
par construire un A. Donc, lorsque le constructeur de A est
appelé, il ne sait pas que l'objet est un AA.
Il sait juste que c'est un A et ne peut donc faire de
résolution dynamique à ce moment là.
Vu autrement, lorsqu'un A est construit, il l'est avec une
vtable de A. Il n'a donc pas accès à la vtable de AA qui ne
sera « construite » que lors de la construction du AA (et
donc, une fois le A déjà construit).
Suis-je condamné à descendre l'appel à maMethode dans le
corps du constructeur de AA et des autres classes filles ?
Une autre idée ?
Oui. À moins, par exemple, de passer par une factory amie qui
appellerait maMethode() juste après la construction.
meow wrote:class A{
private :
B b;
public :
A(B &bb):b(bb){ maMethode(); }
private :
virtual void maMethode()=0;
}
class AA:public A{
public :
AA(B &bb):A(bb){}
// avec une définition correcte de maMethode()
}
Ce qui ne marche pas parce que le linker semble chercher
A::maMethode()...
Oui. Il n'y a pas d'appel virtuel possible dans un
constructeur.
Dans le cas ci-contre, lorsqu'on construit un AA, on commence
par construire un A. Donc, lorsque le constructeur de A est
appelé, il ne sait pas que l'objet est un AA.
Il sait juste que c'est un A et ne peut donc faire de
résolution dynamique à ce moment là.
Vu autrement, lorsqu'un A est construit, il l'est avec une
vtable de A. Il n'a donc pas accès à la vtable de AA qui ne
sera « construite » que lors de la construction du AA (et
donc, une fois le A déjà construit).
Suis-je condamné à descendre l'appel à maMethode dans le
corps du constructeur de AA et des autres classes filles ?
Une autre idée ?
Oui. À moins, par exemple, de passer par une factory amie qui
appellerait maMethode() juste après la construction.
Oui. Il n'y a pas d'appel virtuel possible dans un
constructeur.
Bien sûr que si. L'appel virtuel marche de la même façon que
n'importe où ailleur. La fonction à appeler est choisie en
fonction du type dynamique de l'objet.
Oui, mais quand j'appelle une fonction à travers un A*, on ne
sait pas non plus qu'on a un objet de type AA.
C'est plutôt l'inverse, je crois. Ici, lors de l'appelle de
maMethode dans A::A, le compilateur sait bien que le type
dynamique est A, parce que le type dynamique d'un objet lors de
l'exécution du constructeur est le type du constructeur, par
définition. [...]
Oui. Il n'y a pas d'appel virtuel possible dans un
constructeur.
Bien sûr que si. L'appel virtuel marche de la même façon que
n'importe où ailleur. La fonction à appeler est choisie en
fonction du type dynamique de l'objet.
Oui, mais quand j'appelle une fonction à travers un A*, on ne
sait pas non plus qu'on a un objet de type AA.
C'est plutôt l'inverse, je crois. Ici, lors de l'appelle de
maMethode dans A::A, le compilateur sait bien que le type
dynamique est A, parce que le type dynamique d'un objet lors de
l'exécution du constructeur est le type du constructeur, par
définition. [...]
Oui. Il n'y a pas d'appel virtuel possible dans un
constructeur.
Bien sûr que si. L'appel virtuel marche de la même façon que
n'importe où ailleur. La fonction à appeler est choisie en
fonction du type dynamique de l'objet.
Oui, mais quand j'appelle une fonction à travers un A*, on ne
sait pas non plus qu'on a un objet de type AA.
C'est plutôt l'inverse, je crois. Ici, lors de l'appelle de
maMethode dans A::A, le compilateur sait bien que le type
dynamique est A, parce que le type dynamique d'un objet lors de
l'exécution du constructeur est le type du constructeur, par
définition. [...]
kanze wrote on 11/07/2006 19:40:
Oui. Il n'y a pas d'appel virtuel possible dans un
constructeur.
Bien sûr que si. L'appel virtuel marche de la même façon que
n'importe où ailleur. La fonction à appeler est choisie en
fonction du type dynamique de l'objet.
non, il n'est pas "virtuel", pour la bonne raison exposé par Arnaud.
le fait que dans une arborescense à 15 étages, un appel fait depuis le
7ième ira en effet chercher la méthode du RDC au 7ième n'est pas ce
qu'attends le PO (ni toute "personne normale"); tu dois confondre avec
un langage à "grandes faiblesses" qui lui gère cela très bien.
C'est plutôt l'inverse, je crois. Ici, lors de l'appelle de maMethode
dans A::A, le compilateur sait bien que le type dynamique est A,
parce que le type dynamique d'un objet lors de l'exécution du
constructeur est le type du constructeur, par définition. [...]
et c'est ce que l'on "reproche" !
(comme le fait de ne pas pouvoir appeller un constructeur de la même
classe depuis un constructeur).
tu réponds que l'on /peut/ faire intervenir les pattern design X ou Y,
le fait est que l'on /doit/ complexifier l'écriture via un tel design.
kanze wrote on 11/07/2006 19:40:
Oui. Il n'y a pas d'appel virtuel possible dans un
constructeur.
Bien sûr que si. L'appel virtuel marche de la même façon que
n'importe où ailleur. La fonction à appeler est choisie en
fonction du type dynamique de l'objet.
non, il n'est pas "virtuel", pour la bonne raison exposé par Arnaud.
le fait que dans une arborescense à 15 étages, un appel fait depuis le
7ième ira en effet chercher la méthode du RDC au 7ième n'est pas ce
qu'attends le PO (ni toute "personne normale"); tu dois confondre avec
un langage à "grandes faiblesses" qui lui gère cela très bien.
C'est plutôt l'inverse, je crois. Ici, lors de l'appelle de maMethode
dans A::A, le compilateur sait bien que le type dynamique est A,
parce que le type dynamique d'un objet lors de l'exécution du
constructeur est le type du constructeur, par définition. [...]
et c'est ce que l'on "reproche" !
(comme le fait de ne pas pouvoir appeller un constructeur de la même
classe depuis un constructeur).
tu réponds que l'on /peut/ faire intervenir les pattern design X ou Y,
le fait est que l'on /doit/ complexifier l'écriture via un tel design.
kanze wrote on 11/07/2006 19:40:
Oui. Il n'y a pas d'appel virtuel possible dans un
constructeur.
Bien sûr que si. L'appel virtuel marche de la même façon que
n'importe où ailleur. La fonction à appeler est choisie en
fonction du type dynamique de l'objet.
non, il n'est pas "virtuel", pour la bonne raison exposé par Arnaud.
le fait que dans une arborescense à 15 étages, un appel fait depuis le
7ième ira en effet chercher la méthode du RDC au 7ième n'est pas ce
qu'attends le PO (ni toute "personne normale"); tu dois confondre avec
un langage à "grandes faiblesses" qui lui gère cela très bien.
C'est plutôt l'inverse, je crois. Ici, lors de l'appelle de maMethode
dans A::A, le compilateur sait bien que le type dynamique est A,
parce que le type dynamique d'un objet lors de l'exécution du
constructeur est le type du constructeur, par définition. [...]
et c'est ce que l'on "reproche" !
(comme le fait de ne pas pouvoir appeller un constructeur de la même
classe depuis un constructeur).
tu réponds que l'on /peut/ faire intervenir les pattern design X ou Y,
le fait est que l'on /doit/ complexifier l'écriture via un tel design.
Ça serait mieux que tu apprends un peu de C++ avant de t'avancer. Si la
fonction est déclarée virtuelle, la résolution dynamique s'applique.
Que la fonction soit appelée dans le constructeur, ou ailleurs.
et c'est ce que l'on "reproche" !
Jusqu'ici, je n'ai pas entendu de reproches.
Le problème, d'après mon
expérience (concrète), c'est plutôt avec la façon que fait Java, où on
se trouve dans une fonction membre sur un objet dont le constructeur n'a
pas encore été appelé. C'est une source d'erreurs importante.
(comme le fait de ne pas pouvoir appeller un constructeur de la même
classe depuis un constructeur).
On est en train de l'ajouter. Mais la sémantique n'est pas forcément
évidente.
(Encore, c'est plus facile en Java à cause de l'absence des
destructeurs. Ce qui a, en revanche, d'autres désavantages.)
C'est le prix à payer pour la correction. C'est pareil dans d'autres
langages, avec la différence qu'en C++, tu as un comportement indéfini
(mais un core dump avec un bon compilateur), tandis qu'en Java, tu as
une NullPointerException, sinon un résutlat erroné.
C'est un des cas où le C++ fait mieux que le Java, indiscutablement,
pour celui qui tient à du code robuste.
Ça serait mieux que tu apprends un peu de C++ avant de t'avancer. Si la
fonction est déclarée virtuelle, la résolution dynamique s'applique.
Que la fonction soit appelée dans le constructeur, ou ailleurs.
et c'est ce que l'on "reproche" !
Jusqu'ici, je n'ai pas entendu de reproches.
Le problème, d'après mon
expérience (concrète), c'est plutôt avec la façon que fait Java, où on
se trouve dans une fonction membre sur un objet dont le constructeur n'a
pas encore été appelé. C'est une source d'erreurs importante.
(comme le fait de ne pas pouvoir appeller un constructeur de la même
classe depuis un constructeur).
On est en train de l'ajouter. Mais la sémantique n'est pas forcément
évidente.
(Encore, c'est plus facile en Java à cause de l'absence des
destructeurs. Ce qui a, en revanche, d'autres désavantages.)
C'est le prix à payer pour la correction. C'est pareil dans d'autres
langages, avec la différence qu'en C++, tu as un comportement indéfini
(mais un core dump avec un bon compilateur), tandis qu'en Java, tu as
une NullPointerException, sinon un résutlat erroné.
C'est un des cas où le C++ fait mieux que le Java, indiscutablement,
pour celui qui tient à du code robuste.
Ça serait mieux que tu apprends un peu de C++ avant de t'avancer. Si la
fonction est déclarée virtuelle, la résolution dynamique s'applique.
Que la fonction soit appelée dans le constructeur, ou ailleurs.
et c'est ce que l'on "reproche" !
Jusqu'ici, je n'ai pas entendu de reproches.
Le problème, d'après mon
expérience (concrète), c'est plutôt avec la façon que fait Java, où on
se trouve dans une fonction membre sur un objet dont le constructeur n'a
pas encore été appelé. C'est une source d'erreurs importante.
(comme le fait de ne pas pouvoir appeller un constructeur de la même
classe depuis un constructeur).
On est en train de l'ajouter. Mais la sémantique n'est pas forcément
évidente.
(Encore, c'est plus facile en Java à cause de l'absence des
destructeurs. Ce qui a, en revanche, d'autres désavantages.)
C'est le prix à payer pour la correction. C'est pareil dans d'autres
langages, avec la différence qu'en C++, tu as un comportement indéfini
(mais un core dump avec un bon compilateur), tandis qu'en Java, tu as
une NullPointerException, sinon un résutlat erroné.
C'est un des cas où le C++ fait mieux que le Java, indiscutablement,
pour celui qui tient à du code robuste.
kanze wrote on 11/07/2006 19:40:L'appel virtuel marche de la même façon que
n'importe où ailleur. La fonction à appeler est choisie en
fonction du type dynamique de l'objet.
non, il n'est pas "virtuel", pour la bonne raison exposé par Arnaud.
kanze wrote on 11/07/2006 19:40:
L'appel virtuel marche de la même façon que
n'importe où ailleur. La fonction à appeler est choisie en
fonction du type dynamique de l'objet.
non, il n'est pas "virtuel", pour la bonne raison exposé par Arnaud.
kanze wrote on 11/07/2006 19:40:L'appel virtuel marche de la même façon que
n'importe où ailleur. La fonction à appeler est choisie en
fonction du type dynamique de l'objet.
non, il n'est pas "virtuel", pour la bonne raison exposé par Arnaud.
James Kanze wrote on 11/07/2006 23:50:Ça serait mieux que tu apprends un peu de C++ avant de
t'avancer. Si la fonction est déclarée virtuelle, la
résolution dynamique s'applique.
avec un périmêtre constraint par le lieu d'appel (ici un
constructeur parent particulier).
Que la fonction soit appelée dans le constructeur, ou
ailleurs.
struct A {
A() { init(); }
void doInit() { init(); }
virtual void init() {}
};
struct B : A {
B() : A() {}
void init() {}
};
B b; // invoque A::init();
b.doInit(); // invoque B::init();
donc que la "fonction soit appelée dans le cst ou ailleurs"
est inexact.
et c'est ce que l'on "reproche" !
Jusqu'ici, je n'ai pas entendu de reproches.
change par "ce que l'on regrette" si cela t'aide à adresser
cette "particularité".
Le problème, d'après mon expérience (concrète), c'est plutôt
avec la façon que fait Java, où on se trouve dans une
fonction membre sur un objet dont le constructeur n'a pas
encore été appelé. C'est une source d'erreurs importante.
si tu appelles les fonction membres sans faire un new sur
l'instance avant, oui c'est génant, mais c'est une erreur de
débutant ...
(Encore, c'est plus facile en Java à cause de l'absence des
destructeurs. Ce qui a, en revanche, d'autres désavantages.)
hein ? quel rapport ? gérer un delete this au milieu du
destructeur ?
C'est le prix à payer pour la correction. C'est pareil dans
d'autres langages, avec la différence qu'en C++, tu as un
comportement indéfini (mais un core dump avec un bon
compilateur), tandis qu'en Java, tu as une
NullPointerException, sinon un résutlat erroné.
la comparaison n'a aucun sens - les instances statiques
n'existent pas en Java "point"
-- et obtenir une NullPointerException est justement agréable,
rappelle-nous le compotement défini par le norme pour le code
C++ suivant :
UneClasseValide* ptr;
ptr->UneMethodeValide();
C'est un des cas où le C++ fait mieux que le Java,
indiscutablement, pour celui qui tient à du code robuste.
rien à voir; "pour celui qui ne veux gérer que des instances
statiques" si tu le souhaites.
James Kanze wrote on 11/07/2006 23:50:
Ça serait mieux que tu apprends un peu de C++ avant de
t'avancer. Si la fonction est déclarée virtuelle, la
résolution dynamique s'applique.
avec un périmêtre constraint par le lieu d'appel (ici un
constructeur parent particulier).
Que la fonction soit appelée dans le constructeur, ou
ailleurs.
struct A {
A() { init(); }
void doInit() { init(); }
virtual void init() {}
};
struct B : A {
B() : A() {}
void init() {}
};
B b; // invoque A::init();
b.doInit(); // invoque B::init();
donc que la "fonction soit appelée dans le cst ou ailleurs"
est inexact.
et c'est ce que l'on "reproche" !
Jusqu'ici, je n'ai pas entendu de reproches.
change par "ce que l'on regrette" si cela t'aide à adresser
cette "particularité".
Le problème, d'après mon expérience (concrète), c'est plutôt
avec la façon que fait Java, où on se trouve dans une
fonction membre sur un objet dont le constructeur n'a pas
encore été appelé. C'est une source d'erreurs importante.
si tu appelles les fonction membres sans faire un new sur
l'instance avant, oui c'est génant, mais c'est une erreur de
débutant ...
(Encore, c'est plus facile en Java à cause de l'absence des
destructeurs. Ce qui a, en revanche, d'autres désavantages.)
hein ? quel rapport ? gérer un delete this au milieu du
destructeur ?
C'est le prix à payer pour la correction. C'est pareil dans
d'autres langages, avec la différence qu'en C++, tu as un
comportement indéfini (mais un core dump avec un bon
compilateur), tandis qu'en Java, tu as une
NullPointerException, sinon un résutlat erroné.
la comparaison n'a aucun sens - les instances statiques
n'existent pas en Java "point"
-- et obtenir une NullPointerException est justement agréable,
rappelle-nous le compotement défini par le norme pour le code
C++ suivant :
UneClasseValide* ptr;
ptr->UneMethodeValide();
C'est un des cas où le C++ fait mieux que le Java,
indiscutablement, pour celui qui tient à du code robuste.
rien à voir; "pour celui qui ne veux gérer que des instances
statiques" si tu le souhaites.
James Kanze wrote on 11/07/2006 23:50:Ça serait mieux que tu apprends un peu de C++ avant de
t'avancer. Si la fonction est déclarée virtuelle, la
résolution dynamique s'applique.
avec un périmêtre constraint par le lieu d'appel (ici un
constructeur parent particulier).
Que la fonction soit appelée dans le constructeur, ou
ailleurs.
struct A {
A() { init(); }
void doInit() { init(); }
virtual void init() {}
};
struct B : A {
B() : A() {}
void init() {}
};
B b; // invoque A::init();
b.doInit(); // invoque B::init();
donc que la "fonction soit appelée dans le cst ou ailleurs"
est inexact.
et c'est ce que l'on "reproche" !
Jusqu'ici, je n'ai pas entendu de reproches.
change par "ce que l'on regrette" si cela t'aide à adresser
cette "particularité".
Le problème, d'après mon expérience (concrète), c'est plutôt
avec la façon que fait Java, où on se trouve dans une
fonction membre sur un objet dont le constructeur n'a pas
encore été appelé. C'est une source d'erreurs importante.
si tu appelles les fonction membres sans faire un new sur
l'instance avant, oui c'est génant, mais c'est une erreur de
débutant ...
(Encore, c'est plus facile en Java à cause de l'absence des
destructeurs. Ce qui a, en revanche, d'autres désavantages.)
hein ? quel rapport ? gérer un delete this au milieu du
destructeur ?
C'est le prix à payer pour la correction. C'est pareil dans
d'autres langages, avec la différence qu'en C++, tu as un
comportement indéfini (mais un core dump avec un bon
compilateur), tandis qu'en Java, tu as une
NullPointerException, sinon un résutlat erroné.
la comparaison n'a aucun sens - les instances statiques
n'existent pas en Java "point"
-- et obtenir une NullPointerException est justement agréable,
rappelle-nous le compotement défini par le norme pour le code
C++ suivant :
UneClasseValide* ptr;
ptr->UneMethodeValide();
C'est un des cas où le C++ fait mieux que le Java,
indiscutablement, pour celui qui tient à du code robuste.
rien à voir; "pour celui qui ne veux gérer que des instances
statiques" si tu le souhaites.
Bien sûr que si. L'appel virtuel marche de la même façon que
n'importe où ailleur. La fonction à appeler est choisie en
fonction du type dynamique de l'objet.
Ce qu'il ne faut pas oublier, en revanche, c'est que pendant
l'exécution d'un constructeur (et d'un destructeur), le type
dynamique est celui du constructeur (ou destructeur), et non
celui qu'il sera par la suite.
Oui, mais quand j'appelle une fonction à travers un A*, on ne
sait pas non plus qu'on a un objet de type AA.
Bien sûr que si. L'appel virtuel marche de la même façon que
n'importe où ailleur. La fonction à appeler est choisie en
fonction du type dynamique de l'objet.
Ce qu'il ne faut pas oublier, en revanche, c'est que pendant
l'exécution d'un constructeur (et d'un destructeur), le type
dynamique est celui du constructeur (ou destructeur), et non
celui qu'il sera par la suite.
Oui, mais quand j'appelle une fonction à travers un A*, on ne
sait pas non plus qu'on a un objet de type AA.
Bien sûr que si. L'appel virtuel marche de la même façon que
n'importe où ailleur. La fonction à appeler est choisie en
fonction du type dynamique de l'objet.
Ce qu'il ne faut pas oublier, en revanche, c'est que pendant
l'exécution d'un constructeur (et d'un destructeur), le type
dynamique est celui du constructeur (ou destructeur), et non
celui qu'il sera par la suite.
Oui, mais quand j'appelle une fonction à travers un A*, on ne
sait pas non plus qu'on a un objet de type AA.
kanze wrote:Bien sûr que si. L'appel virtuel marche de la même façon que
n'importe où ailleur. La fonction à appeler est choisie en
fonction du type dynamique de l'objet.
Ciel ! Effectivement. Tout se passe comme s'il ne l'était pas
mais il l'est.
Ce qu'il ne faut pas oublier, en revanche, c'est que pendant
l'exécution d'un constructeur (et d'un destructeur), le type
dynamique est celui du constructeur (ou destructeur), et non
celui qu'il sera par la suite.
En fait, la résolution est bien dynamique dans le sens qu'elle
passe par la vtable, mais c'est la vtable de l'objet en train
d'être construit et non celle de l'objet final. C'est bien
ça ?
Oui, mais quand j'appelle une fonction à travers un A*, on
ne sait pas non plus qu'on a un objet de type AA.
Certes, mais la vtable est correcte à ce moment là (en
considérant une implémentation par vtable. Il me semble qu'il
y a d'autres possibilités, mais je ne les ai jamais
rencontrées).
kanze wrote:
Bien sûr que si. L'appel virtuel marche de la même façon que
n'importe où ailleur. La fonction à appeler est choisie en
fonction du type dynamique de l'objet.
Ciel ! Effectivement. Tout se passe comme s'il ne l'était pas
mais il l'est.
Ce qu'il ne faut pas oublier, en revanche, c'est que pendant
l'exécution d'un constructeur (et d'un destructeur), le type
dynamique est celui du constructeur (ou destructeur), et non
celui qu'il sera par la suite.
En fait, la résolution est bien dynamique dans le sens qu'elle
passe par la vtable, mais c'est la vtable de l'objet en train
d'être construit et non celle de l'objet final. C'est bien
ça ?
Oui, mais quand j'appelle une fonction à travers un A*, on
ne sait pas non plus qu'on a un objet de type AA.
Certes, mais la vtable est correcte à ce moment là (en
considérant une implémentation par vtable. Il me semble qu'il
y a d'autres possibilités, mais je ne les ai jamais
rencontrées).
kanze wrote:Bien sûr que si. L'appel virtuel marche de la même façon que
n'importe où ailleur. La fonction à appeler est choisie en
fonction du type dynamique de l'objet.
Ciel ! Effectivement. Tout se passe comme s'il ne l'était pas
mais il l'est.
Ce qu'il ne faut pas oublier, en revanche, c'est que pendant
l'exécution d'un constructeur (et d'un destructeur), le type
dynamique est celui du constructeur (ou destructeur), et non
celui qu'il sera par la suite.
En fait, la résolution est bien dynamique dans le sens qu'elle
passe par la vtable, mais c'est la vtable de l'objet en train
d'être construit et non celle de l'objet final. C'est bien
ça ?
Oui, mais quand j'appelle une fonction à travers un A*, on
ne sait pas non plus qu'on a un objet de type AA.
Certes, mais la vtable est correcte à ce moment là (en
considérant une implémentation par vtable. Il me semble qu'il
y a d'autres possibilités, mais je ne les ai jamais
rencontrées).
Comme tu sais, le langage n'impose pas de vtable:-). Mais en
effet, c'est à peu près comme ça dans toutes les implémentations
que je connais.
constructeur de T. (En Java, c'est très facile de se trouver
dans une fonction sur un objet dont le constructeur n'a pas
encore été appelé.)
Comme tu sais, le langage n'impose pas de vtable:-). Mais en
effet, c'est à peu près comme ça dans toutes les implémentations
que je connais.
constructeur de T. (En Java, c'est très facile de se trouver
dans une fonction sur un objet dont le constructeur n'a pas
encore été appelé.)
Comme tu sais, le langage n'impose pas de vtable:-). Mais en
effet, c'est à peu près comme ça dans toutes les implémentations
que je connais.
constructeur de T. (En Java, c'est très facile de se trouver
dans une fonction sur un objet dont le constructeur n'a pas
encore été appelé.)