Azuriel wrote on 28/09/2006 19:34:Est-ce possible de déclarer une propriété de même classe que celle
qui la possède ?
class A
{
A a;
};
Je suis vraiment trop con. C'est conceptuellement idiot ;)
non, ni idiot, ni inutile;
Si si, je voulais *vraiment* que A contient une instance de
lui-même en propriété et pas une référence ;). Quel idiot...cela peut même être une façon de coder un noeud dans un
arbre ou une liste chainée (ok, depuis std::/set/ qui ferait
ça?).
l'auto-référencement impose simplement que la donnée membre
soit une référence ou un pointeur (les 2 valant pour un
pointeur de taille connu alors que la classe est de taille
inconnue lorsque la donnée 'a' est parsée - ce qui provoque
l'impossibilité de compiler).
donc:
class A {
A& a;
A(A another) : a(another) { ... }
};
Pour le cas du pointeur, c'est trivial, par contre pour les
références, j'aimerais un exemple qui compile dans ce cas et
utilisable car je n'y arrive pas.
Puisqu'il faut forcément fournir un nouveau A au constructeur
de A, comment créer un A "originel" sans rien lui fournir ?
Azuriel wrote on 28/09/2006 19:34:
Est-ce possible de déclarer une propriété de même classe que celle
qui la possède ?
class A
{
A a;
};
Je suis vraiment trop con. C'est conceptuellement idiot ;)
non, ni idiot, ni inutile;
Si si, je voulais *vraiment* que A contient une instance de
lui-même en propriété et pas une référence ;). Quel idiot...
cela peut même être une façon de coder un noeud dans un
arbre ou une liste chainée (ok, depuis std::/set/ qui ferait
ça?).
l'auto-référencement impose simplement que la donnée membre
soit une référence ou un pointeur (les 2 valant pour un
pointeur de taille connu alors que la classe est de taille
inconnue lorsque la donnée 'a' est parsée - ce qui provoque
l'impossibilité de compiler).
donc:
class A {
A& a;
A(A another) : a(another) { ... }
};
Pour le cas du pointeur, c'est trivial, par contre pour les
références, j'aimerais un exemple qui compile dans ce cas et
utilisable car je n'y arrive pas.
Puisqu'il faut forcément fournir un nouveau A au constructeur
de A, comment créer un A "originel" sans rien lui fournir ?
Azuriel wrote on 28/09/2006 19:34:Est-ce possible de déclarer une propriété de même classe que celle
qui la possède ?
class A
{
A a;
};
Je suis vraiment trop con. C'est conceptuellement idiot ;)
non, ni idiot, ni inutile;
Si si, je voulais *vraiment* que A contient une instance de
lui-même en propriété et pas une référence ;). Quel idiot...cela peut même être une façon de coder un noeud dans un
arbre ou une liste chainée (ok, depuis std::/set/ qui ferait
ça?).
l'auto-référencement impose simplement que la donnée membre
soit une référence ou un pointeur (les 2 valant pour un
pointeur de taille connu alors que la classe est de taille
inconnue lorsque la donnée 'a' est parsée - ce qui provoque
l'impossibilité de compiler).
donc:
class A {
A& a;
A(A another) : a(another) { ... }
};
Pour le cas du pointeur, c'est trivial, par contre pour les
références, j'aimerais un exemple qui compile dans ce cas et
utilisable car je n'y arrive pas.
Puisqu'il faut forcément fournir un nouveau A au constructeur
de A, comment créer un A "originel" sans rien lui fournir ?
Azuriel wrote on 28/09/2006 20:17:class A {
A& a;
A(A another) : a(another) { ... }
};
Pour le cas du pointeur, c'est trivial, par contre pour les référen ces,
j'aimerais un exemple qui compile dans ce cas et utilisable car je n'y
arrive pas.
Puisqu'il faut forcément fournir un nouveau A au constructeur de A,
comment créer un A "originel" sans rien lui fournir ?
;-) !
faute de pouvoir ne rien lui fournir, on peut lui fournir rien
en le faisant passer pour qlq chose ...
A* first = null;
A a(*first);
une référence (hormis la simplification syntaxique) est
l'équivalent d'un pointeur, donc on peut lui affecter une
valeur nulle (tester cette valeur ne conduira pas à un code
très clean mais bon ...).
Azuriel wrote on 28/09/2006 20:17:
class A {
A& a;
A(A another) : a(another) { ... }
};
Pour le cas du pointeur, c'est trivial, par contre pour les référen ces,
j'aimerais un exemple qui compile dans ce cas et utilisable car je n'y
arrive pas.
Puisqu'il faut forcément fournir un nouveau A au constructeur de A,
comment créer un A "originel" sans rien lui fournir ?
;-) !
faute de pouvoir ne rien lui fournir, on peut lui fournir rien
en le faisant passer pour qlq chose ...
A* first = null;
A a(*first);
une référence (hormis la simplification syntaxique) est
l'équivalent d'un pointeur, donc on peut lui affecter une
valeur nulle (tester cette valeur ne conduira pas à un code
très clean mais bon ...).
Azuriel wrote on 28/09/2006 20:17:class A {
A& a;
A(A another) : a(another) { ... }
};
Pour le cas du pointeur, c'est trivial, par contre pour les référen ces,
j'aimerais un exemple qui compile dans ce cas et utilisable car je n'y
arrive pas.
Puisqu'il faut forcément fournir un nouveau A au constructeur de A,
comment créer un A "originel" sans rien lui fournir ?
;-) !
faute de pouvoir ne rien lui fournir, on peut lui fournir rien
en le faisant passer pour qlq chose ...
A* first = null;
A a(*first);
une référence (hormis la simplification syntaxique) est
l'équivalent d'un pointeur, donc on peut lui affecter une
valeur nulle (tester cette valeur ne conduira pas à un code
très clean mais bon ...).
Michel Decima wrote on 28/09/2006 21:50:Sylvain wrote:faute de pouvoir ne rien lui fournir, on peut lui fournir rien en le
faisant passer pour qlq chose ...
A* first = null;
A a(*first);
Est ce que *first a un comportement defini si first vaut NULL ?
quelle importance puisqu'il N'est PAS déréférencé ...
Michel Decima wrote on 28/09/2006 21:50:
Sylvain wrote:
faute de pouvoir ne rien lui fournir, on peut lui fournir rien en le
faisant passer pour qlq chose ...
A* first = null;
A a(*first);
Est ce que *first a un comportement defini si first vaut NULL ?
quelle importance puisqu'il N'est PAS déréférencé ...
Michel Decima wrote on 28/09/2006 21:50:Sylvain wrote:faute de pouvoir ne rien lui fournir, on peut lui fournir rien en le
faisant passer pour qlq chose ...
A* first = null;
A a(*first);
Est ce que *first a un comportement defini si first vaut NULL ?
quelle importance puisqu'il N'est PAS déréférencé ...
class A
{
public:
A() : a( *this ) {}
private:
A& a ;
} ;
Quant à l'utilité, c'est autre chose:-). Dans la pratique, quand
on veut une référence au même type dans un objet, c'est pour la
navigation, et il faut pouvoir changer le référé dynamiquement.
Ce qui veut dire pointeur, et non référence.
class A
{
public:
A() : a( *this ) {}
private:
A& a ;
} ;
Quant à l'utilité, c'est autre chose:-). Dans la pratique, quand
on veut une référence au même type dans un objet, c'est pour la
navigation, et il faut pouvoir changer le référé dynamiquement.
Ce qui veut dire pointeur, et non référence.
class A
{
public:
A() : a( *this ) {}
private:
A& a ;
} ;
Quant à l'utilité, c'est autre chose:-). Dans la pratique, quand
on veut une référence au même type dans un objet, c'est pour la
navigation, et il faut pouvoir changer le référé dynamiquement.
Ce qui veut dire pointeur, et non référence.
Sylvain wrote:Michel Decima wrote on 28/09/2006 21:50:Sylvain wrote:faute de pouvoir ne rien lui fournir, on peut lui fournir rien en le
faisant passer pour qlq chose ...
A* first = null;
A a(*first);
Est ce que *first a un comportement defini si first vaut NULL ?
quelle importance puisqu'il N'est PAS déréférencé ...
Et c'est quoi, exactement, l'expression *first, si ce n'est pas
la déférencement de first.
Sylvain wrote:
Michel Decima wrote on 28/09/2006 21:50:
Sylvain wrote:
faute de pouvoir ne rien lui fournir, on peut lui fournir rien en le
faisant passer pour qlq chose ...
A* first = null;
A a(*first);
Est ce que *first a un comportement defini si first vaut NULL ?
quelle importance puisqu'il N'est PAS déréférencé ...
Et c'est quoi, exactement, l'expression *first, si ce n'est pas
la déférencement de first.
Sylvain wrote:Michel Decima wrote on 28/09/2006 21:50:Sylvain wrote:faute de pouvoir ne rien lui fournir, on peut lui fournir rien en le
faisant passer pour qlq chose ...
A* first = null;
A a(*first);
Est ce que *first a un comportement defini si first vaut NULL ?
quelle importance puisqu'il N'est PAS déréférencé ...
Et c'est quoi, exactement, l'expression *first, si ce n'est pas
la déférencement de first.
*first n'implique pas forcément un déréférencement 'mécanique' du
pointeur first.
int *p = 0;
int &r = *p; // pas de déréférencement, seule l'adresse est
//utilisée => ok
int v = *p; // déréférencement => crash
La seconde ligne DOIT passer sur n'importe quel compilateur (warning au
maximum).
*first n'implique pas forcément un déréférencement 'mécanique' du
pointeur first.
int *p = 0;
int &r = *p; // pas de déréférencement, seule l'adresse est
//utilisée => ok
int v = *p; // déréférencement => crash
La seconde ligne DOIT passer sur n'importe quel compilateur (warning au
maximum).
*first n'implique pas forcément un déréférencement 'mécanique' du
pointeur first.
int *p = 0;
int &r = *p; // pas de déréférencement, seule l'adresse est
//utilisée => ok
int v = *p; // déréférencement => crash
La seconde ligne DOIT passer sur n'importe quel compilateur (warning au
maximum).
*first n'implique pas forcément un déréférencement 'mécanique ' du
pointeur first.
int *p = 0;
int &r = *p; // pas de déréférencement, seule l'adresse est
//utilisée => ok
int v = *p; // déréférencement => crash
La seconde ligne DOIT passer sur n'importe quel compilateur (warning au
maximum).
Qu'est ce qui JUSTIFIE cette affirmation dans la norme ?
*first n'implique pas forcément un déréférencement 'mécanique ' du
pointeur first.
int *p = 0;
int &r = *p; // pas de déréférencement, seule l'adresse est
//utilisée => ok
int v = *p; // déréférencement => crash
La seconde ligne DOIT passer sur n'importe quel compilateur (warning au
maximum).
Qu'est ce qui JUSTIFIE cette affirmation dans la norme ?
*first n'implique pas forcément un déréférencement 'mécanique ' du
pointeur first.
int *p = 0;
int &r = *p; // pas de déréférencement, seule l'adresse est
//utilisée => ok
int v = *p; // déréférencement => crash
La seconde ligne DOIT passer sur n'importe quel compilateur (warning au
maximum).
Qu'est ce qui JUSTIFIE cette affirmation dans la norme ?
L'opération d'initialisation d'une référence.
int &r = x;
2 cas :
- "x" est une lvalue ("x" doit être du type de la référence) :
l'opération d'initialisation prend l'adresse de "x" => "x" n'est pas
évalué.
- "x" est une rvalue ("x" ne doit pas forcément être du type de la
référence): Conversion implicite de type + création d'une variable
temporaire. => "x" est évalué. A partir de là, l'initialisation
possède un objet avec une adresse. Par conséquent, retour au premier
cas.
L'opération d'initialisation d'une référence.
int &r = x;
2 cas :
- "x" est une lvalue ("x" doit être du type de la référence) :
l'opération d'initialisation prend l'adresse de "x" => "x" n'est pas
évalué.
- "x" est une rvalue ("x" ne doit pas forcément être du type de la
référence): Conversion implicite de type + création d'une variable
temporaire. => "x" est évalué. A partir de là, l'initialisation
possède un objet avec une adresse. Par conséquent, retour au premier
cas.
L'opération d'initialisation d'une référence.
int &r = x;
2 cas :
- "x" est une lvalue ("x" doit être du type de la référence) :
l'opération d'initialisation prend l'adresse de "x" => "x" n'est pas
évalué.
- "x" est une rvalue ("x" ne doit pas forcément être du type de la
référence): Conversion implicite de type + création d'une variable
temporaire. => "x" est évalué. A partir de là, l'initialisation
possède un objet avec une adresse. Par conséquent, retour au premier
cas.
L'opération d'initialisation d'une référence.
int &r = x;
2 cas :
- "x" est une lvalue ("x" doit être du type de la référence) :
l'opération d'initialisation prend l'adresse de "x" => "x" n'est pas
évalué.
- "x" est une rvalue ("x" ne doit pas forcément être du type de la
référence): Conversion implicite de type + création d'une variable
temporaire. => "x" est évalué. A partir de là, l'initialisation
possède un objet avec une adresse. Par conséquent, retour au premier
cas.
De plus, un comportement non défini devrait (mais ce n'est pas
toujours le cas...) générer de la part du compilateur uniquement un
warning.
L'opération d'initialisation d'une référence.
int &r = x;
2 cas :
- "x" est une lvalue ("x" doit être du type de la référence) :
l'opération d'initialisation prend l'adresse de "x" => "x" n'est pas
évalué.
- "x" est une rvalue ("x" ne doit pas forcément être du type de la
référence): Conversion implicite de type + création d'une variable
temporaire. => "x" est évalué. A partir de là, l'initialisation
possède un objet avec une adresse. Par conséquent, retour au premier
cas.
De plus, un comportement non défini devrait (mais ce n'est pas
toujours le cas...) générer de la part du compilateur uniquement un
warning.
L'opération d'initialisation d'une référence.
int &r = x;
2 cas :
- "x" est une lvalue ("x" doit être du type de la référence) :
l'opération d'initialisation prend l'adresse de "x" => "x" n'est pas
évalué.
- "x" est une rvalue ("x" ne doit pas forcément être du type de la
référence): Conversion implicite de type + création d'une variable
temporaire. => "x" est évalué. A partir de là, l'initialisation
possède un objet avec une adresse. Par conséquent, retour au premier
cas.
De plus, un comportement non défini devrait (mais ce n'est pas
toujours le cas...) générer de la part du compilateur uniquement un
warning.
L'opération d'initialisation d'une référence.
int &r = x;
2 cas :
- "x" est une lvalue ("x" doit être du type de la référence) :
l'opération d'initialisation prend l'adresse de "x" => "x" n'est pas
évalué.
- "x" est une rvalue ("x" ne doit pas forcément être du type de la
référence): Conversion implicite de type + création d'une variable
temporaire. => "x" est évalué. A partir de là, l'initialisation
possède un objet avec une adresse. Par conséquent, retour au premier
cas.
Si je considere
int& r = *(int*)0;
dans lequel des 2 cas on se place ? Quel devrait etre le resultat
de la compilation ?
L'opération d'initialisation d'une référence.
int &r = x;
2 cas :
- "x" est une lvalue ("x" doit être du type de la référence) :
l'opération d'initialisation prend l'adresse de "x" => "x" n'est pas
évalué.
- "x" est une rvalue ("x" ne doit pas forcément être du type de la
référence): Conversion implicite de type + création d'une variable
temporaire. => "x" est évalué. A partir de là, l'initialisation
possède un objet avec une adresse. Par conséquent, retour au premier
cas.
Si je considere
int& r = *(int*)0;
dans lequel des 2 cas on se place ? Quel devrait etre le resultat
de la compilation ?
L'opération d'initialisation d'une référence.
int &r = x;
2 cas :
- "x" est une lvalue ("x" doit être du type de la référence) :
l'opération d'initialisation prend l'adresse de "x" => "x" n'est pas
évalué.
- "x" est une rvalue ("x" ne doit pas forcément être du type de la
référence): Conversion implicite de type + création d'une variable
temporaire. => "x" est évalué. A partir de là, l'initialisation
possède un objet avec une adresse. Par conséquent, retour au premier
cas.
Si je considere
int& r = *(int*)0;
dans lequel des 2 cas on se place ? Quel devrait etre le resultat
de la compilation ?