Cette page vous donne les différences entre la révision choisie et la version actuelle de la page.
conversions [2014/10/10 01:40] gbdivers |
conversions [2015/11/11 20:12] (Version actuelle) 71.93.97.8 [Conversion implicite et explicite] orthographe ajoute |
||
---|---|---|---|
Ligne 6: | Ligne 6: | ||
===== Conversion implicite et explicite ===== | ===== Conversion implicite et explicite ===== | ||
- | on a vu qu'il était possible que le compilateur puisse faire des converison automatiquement (on dit qu'elles sont implicite : http://en.cppreference.com/w/cpp/language/implicit_cast). Par exemple, quand on écrit : | + | On a vu qu'il était possible que le compilateur puisse faire des conversions automatiquement (on dit qu'elles sont implicites : http://en.cppreference.com/w/cpp/language/implicit_cast). Par exemple, quand on écrit : |
<code cpp> | <code cpp> | ||
Ligne 14: | Ligne 14: | ||
La littérale "123" est de type ''int'', la valeur est d'abord convertie en long int avant d'être affectée à la variable l (en pratique, le compilateur sait faire directement cette conversion, cela n'a pas d'impact sur les performances) | La littérale "123" est de type ''int'', la valeur est d'abord convertie en long int avant d'être affectée à la variable l (en pratique, le compilateur sait faire directement cette conversion, cela n'a pas d'impact sur les performances) | ||
- | Dans d'autres cas, la conversion va produire un avertissement (par exemple quand on perd des informations - narrowing ou arrondi) ou s'il n'existe pas de conversion implcite possible. | + | Dans d'autres cas, la conversion va produire un avertissement (par exemple quand on perd des informations - narrowing ou arrondi) ou s'il n'existe pas de conversion implicite possible. |
<code> | <code> | ||
Ligne 21: | Ligne 21: | ||
</code> | </code> | ||
- | Dans un conversion explicite (cast), on ajouter un code qui indique que l'on souhaite faire la conversion. Plusieurs opérateur de cast : | + | Dans un conversion explicite (cast), on ajoute un code qui indique que l'on souhaite faire la conversion. Plusieurs opérateurs de cast : |
* static_cast, vérifié à la compilation, entre types compatibles ; | * static_cast, vérifié à la compilation, entre types compatibles ; | ||
- | * dynamic_cast, vérifié à la compialtion entre classes parent (vu plus loin, avec l'héritage) ; | + | * dynamic_cast, vérifié à la compilation entre classes parent (vu plus loin, avec l'héritage) ; |
- | * reinterpret_cast, sans vérificatio (donc très dangeureux), également pour l'héritage. | + | * reinterpret_cast, sans vérification (donc très dangereux), également pour l'héritage. |
Donc pour le moment, seul qui intéresse : static_cast. Fonction template, il faut indiquer le type que l'on souhaite obtenir comme argument template et la valeur à convertir comme argument de fonction. En cas de cast explicite, le compilateur ne génère pas d'avertissement, il considère que l'on sait ce que l'on fait. | Donc pour le moment, seul qui intéresse : static_cast. Fonction template, il faut indiquer le type que l'on souhaite obtenir comme argument template et la valeur à convertir comme argument de fonction. En cas de cast explicite, le compilateur ne génère pas d'avertissement, il considère que l'on sait ce que l'on fait. | ||
Ligne 56: | Ligne 56: | ||
</code> | </code> | ||
- | Par défaut, il est préférable de bloquer les convesion implicite, sauf si cela a clairement un sens au niveau sémantique. Par exemple, si on écrit une classe Arme, qui prend un int pour les dégats, cela n'a pas de sens d'écrire : Arme a { 10 }; (on ne comprend pas à quoi correspond la valeur 10). Par contre, pour un complexe, écrire complex c { 10 } a un sens puisque 10 est un nombre complexe particulier (c'est un réel, donc un nombre complexe de la forme a+i*0) | + | Par défaut, il est préférable de bloquer les conversion implicite, sauf si cela a clairement un sens au niveau sémantique. Par exemple, si on écrit une classe Arme, qui prend un int pour les dégâts, cela n'a pas de sens d'écrire : Arme a { 10 }; (on ne comprend pas à quoi correspond la valeur 10). Par contre, pour un complexe, écrire complex c { 10 } a un sens puisque 10 est un nombre complexe particulier (c'est un réel, donc un nombre complexe de la forme a+i*0) |
- | Pour interdir l'appel d'un constructeur implicitement, il faut ajouter le mot clé ''explicit'' : | + | Pour interdire l'appel d'un constructeur implicitement, il faut ajouter le mot clé ''explicit'' : |
<code> | <code> | ||
Ligne 66: | Ligne 66: | ||
int main() { | int main() { | ||
- | A a { 123 }; // erreur, implcite conversion | + | A a { 123 }; // erreur, implicite conversion |
A a { static_cast<A>(123) }; // ok, conversion explicite | A a { static_cast<A>(123) }; // ok, conversion explicite | ||
}; | }; | ||
Ligne 88: | Ligne 88: | ||
</code> | </code> | ||
- | Littérales utilisateur | + | Use case for reference qualifier. Cf http://stackoverflow.com/questions/28026352/is-there-any-real-use-case-for-functions-reference-qualifiers |
+ | ===== Littérales utilisateur ===== | ||
Permet d'écrire un littérale correspond à un type crée par l'utilisateur. Par exemple, si on écrit A(int) et que l'on veut utiliser auto, il faudra écrire : | Permet d'écrire un littérale correspond à un type crée par l'utilisateur. Par exemple, si on écrit A(int) et que l'on veut utiliser auto, il faudra écrire : | ||
Ligne 101: | Ligne 102: | ||
</code> | </code> | ||
- | Littérale utilisateur permet d'écirre : | + | Littérale utilisateur permet d'écrire : |
<code cpp> | <code cpp> | ||
Ligne 107: | Ligne 108: | ||
</code> | </code> | ||
- | le suffixe peut être n'importe quoi. Par exmple, pour une classe time (qui enregistre des secodnes) : | + | le suffixe peut être n'importe quoi. Par exemple, pour une classe time (qui enregistre des secondes) : |
<code cpp> | <code cpp> | ||
Ligne 115: | Ligne 116: | ||
</code> | </code> | ||
- | A chaque fois le meme type (time), mais valeur différentes | + | A chaque fois le même type (time), mais valeurs différentes |
signature : | signature : | ||
Ligne 171: | Ligne 172: | ||
remarque : ajouté dans le C++14 | remarque : ajouté dans le C++14 | ||
+ | ===== Exercices ===== | ||
+ | |||
+ | * écrire les opérateurs du C++14 (avec _ en plus) | ||
+ | |||
+ | <code cpp> | ||
+ | std::string operator"" _s (const char* s, std::size_t) { return std::string(s); } | ||
+ | </code> | ||
+ | |||
+ | (remarque : pas de constexpr en C++11 avec string) | ||
^ Chapitre précédent ^ [[programmez_avec_le_langage_c|Sommaire principal]] ^ Chapitre suivant ^ | ^ Chapitre précédent ^ [[programmez_avec_le_langage_c|Sommaire principal]] ^ Chapitre suivant ^ | ||
{{tag> Cours C++}} | {{tag> Cours C++}} |