bonjour
que signifie le terme "never throw". On le voit souvent dans les librairies boost.
http://www.boost.org/doc/libs/1_44_0...m#constructors
bonjour
que signifie le terme "never throw". On le voit souvent dans les librairies boost.
http://www.boost.org/doc/libs/1_44_0...m#constructors
Qu'il ne lancera jamais d'exception.
"Never use brute force in fighting an exponential." (Andrei Alexandrescu)
Mes articles dont Conseils divers sur le C++
Une très bonne doc sur le C++ (en) Why linux is better (fr)
Cela n'a rien a voir avec le message précédent, mais j'aimerais savoir s'il est possible de convertir un pointeur en un autre, qui n'a rien a voir. Par exemple, avec les deux classes suivantes: A et B. On voit que la conversion d'un objet A un élément B fonctionne. Mais la conversion d'un pointeur vers un objet A en un pointeur vers un objet B me renvoie le message:
Error 1 error C2440: '=' : cannot convert from 'A *' to 'B *'
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43 class B{ friend class A; private: int Barg1; public: B(){}; B(int o):Barg1(o){}; }; class A{ private: int arg1; int arg2; public: A(int o,int r):arg1(o),arg2(r){}; operator B(); operator B*(); }; A::operator B(){//conversion de A en B. B b; b.Barg1=this->arg2; return b; } A::operator B*(){//conversion de A* en B*. B b; b.Barg1=arg2; return &b; } void main(){ A g(2,3); B f; f=g;//OKKKKKKKK A* ptra=new A(2,3); B* ptrb=0; ptrb=ptra; ////pas okkkkkkkkkk }
Alors est il possible de faire cela?
Merci
Plusieurs remarques.
Intérêt de pouvoir faire ca ? les conversions pointeurs<->pointeurs sont en général à moitié casse geule (surtout en cas de downcasting) mais je vois _vraiment_ pas l'intérêt de faire du cross-casting (pas d'autres terme sous le clavier)
Dans A::operator B*, tu renvois l'adresse d'une variable locale. Dans l'hypothèse où ton code serait juste, si tu la récupérerais et que tu l'utilisais: boom.
Enfin, il faut comprendre que tes fonctions de conversions sont pour que des OBJETS se transforme en pointeur. Là tu essayes d'affecter un PoINTEUR à un autre pointeur d'un type différent sans lien d'héritage quelconque entre tes cllasses. Ca coince et c'est normal. ptrb=*ptra; marchera beaucoup mieux.
"Never use brute force in fighting an exponential." (Andrei Alexandrescu)
Mes articles dont Conseils divers sur le C++
Une très bonne doc sur le C++ (en) Why linux is better (fr)
en fait, il suffit de faire:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 B* aa=0; aa=(B*)(&g);exacteDans A::operator B*, tu renvois l'adresse d'une variable locale. Dans l'hypothèse où ton code serait juste, si tu la récupérerais et que tu l'utilisais: boom.
c'est pas un peu ce que tu fais quand tu transforme un double en int? Il n'y a a priori pas de relation d'héritage.Enfin, il faut comprendre que tes fonctions de conversions sont pour que des OBJETS se transforme en pointeur. Là tu essayes d'affecter un PoINTEUR à un autre pointeur d'un type différent sans lien d'héritage quelconque entre tes cllasses. Ca coince et c'est normal. ptrb=*ptra; marchera beaucoup mieux.
Là tu forces le cast avec un cast C-like. ces derniers sont à bannir car tu peux faire tout et n'importe quoi. Surtout n'importe quoi d'ailleurs.en fait, il suffit de faire:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 B* aa=0; aa=(B*)(&g);
Dans le cas où tu écris A::operator B*, tu considères que TOUT objet de type A peut être converti en un pointeur de type B.
Si tu veux juster caster pour un objet particulier, utilise reinterpret_cast.
Pas pareil. Ce sont deux types définis par la norme et je ne serais pas étonné que les conversions autorisées soit explicitées dedans.c'est pas un peu ce que tu fais quand tu transforme un double en int? Il n'y a a priori pas de relation d'héritage.
"Never use brute force in fighting an exponential." (Andrei Alexandrescu)
Mes articles dont Conseils divers sur le C++
Une très bonne doc sur le C++ (en) Why linux is better (fr)
Je sais bien que mon code est pas bon, même s'il compile. Mais c'est pour m'entraîner.
en fait, il faut faire:
Mais je voudrais savoir s'il est possible de ne pas avoir a écrire ->operator B*() et avoir une syntaxe plus rapide pour appeler la conversion.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 A g(2,3); B f; f=g; B* aa=0; aa=(&g)->operator B *();
Dans la doc d'un shared_ptr, il est écrit:
template<class Y> explicit shared_ptr(Y * p);
Requirements: p must be convertible to T *. Y must be a complete type. The expression delete p must be well-formed, must not invoke undefined behavior, and must not throw exceptions.
Je veux convertir un pointeur de type Y en T. Donc pour ca, j'ai crée deux classes, mais je voulais pas de conversion d'héritage.
Marche pas:
Je pensais que la conversion pouvait se faire, sans faire appel à un operateur explicitement.
Code : Sélectionner tout - Visualiser dans une fenêtre à part shared_ptr<B> dd(new A(3,2));
Marche:
Code : Sélectionner tout - Visualiser dans une fenêtre à part shared_ptr<B> dd((new A(3,2))->operator B *());
Compile tout aussi bien. Car en faisant (&g)->operator B*(), tu prends l'adresse de g pour ensuite la déférencer ! Autant directement prendre l'objet de base !!!
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 A g(2,3); B f; f=g; B* aa=0; aa=g;
Répond clairement ! QUEL INTERET as tu de faire ca ? Pourquoi essayer de déguiser un pointeur de type A en un pointeur de type B alors que B et A n'ont RIEN en commun ?Je veux convertir un pointeur de type Y en T. Donc pour ca, j'ai crée deux classes, mais je voulais pas de conversion d'héritage.
"Never use brute force in fighting an exponential." (Andrei Alexandrescu)
Mes articles dont Conseils divers sur le C++
Une très bonne doc sur le C++ (en) Why linux is better (fr)
A part manipuler du C++, aucun.Répond clairement ! QUEL INTERET as tu de faire ca ?
Tu ne dravis jamais avoir à faire de tel cast, si c'est le cas c'est qu'il y a très probablement un problème en amont. Et au cas où il n'y aurait aucun problème, un cast entre deux type sans rapport c'est reinterpret_cast (David l'a dit je crois).
Salut,
Il faut comprendre que la conversion de type devrait être considérée de deux sémantiques clairement distinctes
un type peut avoir sémantique de valeur
un type peut avoir sémantique d'entité
Tu as donc quatre possibilités distinctes:
Soit tu travailles avec des types ayant sémantique de valeur, et tu souhaite pouvoir convertir une variable d'un de ces type (par exemple un int, mais cela peut aussi être n'importe quelle classe perso ayant sémantique de valeur) en une variable de l'autre type (par exemple une std::string, mais, là encore, ce peut être n'importe quelle classe perso ayant sémantique de valeur
).
Nous pourrions dire (parce que je n'ai jamais vu ce terme) qu'il s'agit d'une "conversion de facilité" ou d'une "conversion de manipulation", dans le sens où elle te permettra d'utiliser ta variable "autrement" que ce que permet son type d'origine.
La solution pour y arriver est alors de prévoir, selon le cas, soit un constructeur particulier prenant le type d'origine comme argument soit un opérateur de conversion dans l'autre sens, en évitant à tout prix le cast C style qui ouvre réellement la porte à toutes les élucubrations.
Soit tu travailles avec de types ayant sémantique d'entité, et tu veux pouvoir récupérer un "secrétaire" à partir d'un "employé" (pour autant que l'employé soit effectivement un secrétaire) ou, à l'inverse, pouvoir faire passer ton "secrétaire" pour un "employé".
Tu as alors une relation forte entre un secrétaire et un employé, parce qu'un secrétaire... EST-UN employé.
La conversion de secrétaire en employé est donc totalement implicite (pour autant que tu transmette ton secrétaire par pointeur ou par référence (constante ou non) ) et la conversion d'employer en secrétaire doit... veiller à ce que l'employé soit effectivement un secrétaire.
La solution pour être sur de ne pas essayer de faire passer un "vendeur" (qui est aussi un employé) pour un "secrétaire" passe alors par les cast particuliers de C++ que sont static_cast et dynamic_cast ou par le double dyspatch (pattern "visiteur" en tête de liste).
Les deux dernières possibilités sont de vouloir convertir une variable dont le type a sémantique de valeur en une variable dont le type a sémantique d'entité et inversement (obtenir un secrétaire au départ d'une chaine de caractères ou obtenir une chaine de caractères au départ d'un secrétaire).
Nous nous retrouvons alors de nouveau dans un contexte d'une " conversion de facilité" ou "de manipulation" que j'exposais plus haut![]()
A méditer: La solution la plus simple est toujours la moins compliquée
Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
Compiler Gcc sous windows avec MinGW
Coder efficacement en C++ : dans les bacs le 17 février 2014
mon tout nouveau blog
Partager