De commencer la programmation en C ++ pour les nuls

C ++ est plein de petits symboles, dont chacun ajoute à la signification des expressions. Les règles de la grammaire C ++ sont si souples que ces symboles peuvent être combinés dans des combinaisons presque impénétrable complexes. Les expressions dans la langue simple de C peuvent obtenir si obtus que il y avait un concours annuel pour qui pouvait écrire le programme le plus obscur et qui pourrait comprendre.

Sommaire

Il est jamais une bonne idée d'essayer d'écrire du code complexe, mais vous sera parfois courir à travers les expressions en C ++ qui sont un peu déroutant au premier abord. Il suffit d'utiliser les étapes suivantes pour les comprendre:

  1. Commencez par les parenthèses les plus intégrés.

    Commencez à chercher les extérieurs plupart des parenthèses. Dans ceux-ci, chercher des parenthèses embarqués. Répétez le processus jusqu'à ce que vous avez travaillé votre chemin à la paire la plus profonde de parenthèses. Commencer à évaluer ce que sous-expression de la première utilisation, les règles suivantes. Une fois que vous comprenez que l'expression, ressortira au niveau suivant et répétez le processus.

  2. Dans la paire de parenthèses, d'évaluer chaque opération dans l'ordre de préséance.

    L'ordre dans lequel les opérateurs sont évalués est déterminée par la priorité de l'opérateur indiqué dans le tableau. Indirection vient avant la multiplication qui vient avant l'addition donc la suivante ajoute 1 plus 2 fois la valeur pointée par * ptr.

int i = 1 + 2 * * ptr-
Opérateurs par ordre de préséance
PrioritéOpérateurSignification
1() (Unaire)Invoquer une fonction
2* Et -> (unaire)Déréférencer un pointeur
2- (unaire)Retourne le négatif de son argument
3++ (unaire)Incrément
3-- (unaire)Décrément
4* (Binaire)Multiplication
4/ (Binaire)Division
4% (Binaire)Modulo
5+ (binaire)Addition
5- (binaire)Soustraction
6 (binaire)ET logique
6!!OU logique
7=, * =,% =, + =, - = (Spéciale)Types d'affectation
  1. Évaluer les opérations de la même priorité de gauche à droite (sauf cession, qui va dans l'autre sens).

    La plupart des opérateurs de même priorité évaluer de gauche à droite. Ainsi la suivante ajoute 1 à 2 et ajoute le résultat à 3:

    int i = 1 + 2 + 3

    L'ordre d'évaluation de certains opérateurs n'a pas d'importance. Par exemple, fonctionne de la même addition de gauche à droite comme il le fait de droite à gauche. L'ordre d'évaluation fait beaucoup de différence pour certaines opérations comme la division. Les divisions suivantes 8 par 4 et divise le résultat par 2:

    int i = 8/4 / 2-

    La principale exception à cette règle est la cession, qui est évaluée de droite à gauche:

    a = b = c-

    Ceci affecte C à B et le résultat d'un.

  2. Évaluer sous-expressions dans aucun ordre particulier.

    Considérons l'expression suivante:

    int i = f () + g () * h () -



    Multiplication a une priorité plus élevée, de sorte que vous pourriez supposer que les fonctions g () et h () sont appelés avant f (), cependant, c'est pas le cas. Appel de fonction a la priorité la plus élevée de tous, afin que tous les trois fonctions sont appelées soit avant la multiplication ou l'addition est effectuée. (Les résultats renvoyés par g () et h () sont multipliés et ensuite ajoutés aux résultats retournés à partir de f ().)

    La seule fois que l'ordre que les fonctions sont appelées fait une différence est lorsque la fonction a des effets secondaires tels que l'ouverture d'un fichier ou modifier la valeur d'une variable globale. Vous devriez vraiment pas écrire vos programmes afin qu'ils dépendent de ce type d'effets secondaires.

  3. Effectuez toutes les conversions de type uniquement lorsque cela est nécessaire.

    Vous ne devriez pas faire plus de conversions de type absolument nécessaire. Par exemple, l'expression suivante a au moins trois et peut-être quatre conversions de type:

    flotter f = 'a' + 1-

    Le char 'un «doit être promu à un int pour effectuer l'addition. L'int est ensuite converti en un lit double et puis vers le bas converti en un seul flotteur de précision. Rappelez-vous que toute l'arithmétique est effectuée soit dans int ou double. Vous devez généralement éviter arithmétique effectuer sur les types de caractères et d'éviter tout seul flotteur de précision.

5 façons d'éviter les problèmes de pointeur en C ++

En C ++, un aiguille est une variable qui contient l'adresse d'un objet dans la mémoire interne de l'ordinateur. Suivez ces étapes pour éviter les problèmes avec des pointeurs en C ++:

  1. Initialiser pointeurs lorsqu'ils sont déclarés.

    Ne laissez jamais des variables de pointeur non initialisé - les choses ne seraient pas trop mal si pointeurs non initialisées contiennent toujours des valeurs aléatoires - la grande majorité des valeurs aléatoires sont des valeurs de pointeur illégale, elle provoquera un plantage du programme dès qu'ils sont utilisés. Le problème est que les variables non initialisées ont tendance à prendre de la valeur des autres variables de pointeur, utilisés précédemment. Ces problèmes sont très difficiles à déboguer.

    Si vous ne savez pas quoi initialiser un pointeur vers, initialiser à nullptr. nullptr est garanti d'être une adresse illégale.

  2. Zéro sur pointeurs après que vous les utilisez.

    De même, toujours zéro une variable pointeur une fois que le pointeur est plus valable en lui attribuant la valeur nullptr. Ceci est particulièrement le cas lorsque vous revenez d'un bloc de mémoire sur le tas en utilisant Delete- zéro toujours le pointeur après le retour mémoire de tas.

  3. Allouer de la mémoire à partir du tas et de le retourner au tas au même "niveau" pour éviter les fuites de mémoire.

    Toujours essayer de revenir un bloc de mémoire sur le tas au même niveau d'abstraction que vous lui étaient allouées. Cela signifie généralement que d'essayer de supprimer la mémoire au même niveau d'appels de fonction.

  4. Attrapez une exception à supprimer la mémoire si nécessaire.

    Ne pas oublier qu'une exception peut se produire à presque tout moment. Si vous avez l'intention d'attraper l'exception et continuera exploitation (plutôt que de laisser le plantage du programme), assurez-vous que vous attrapez l'exception et retourner tous les blocs de mémoire sur le tas avant les pointeurs qui pointent vers eux sortent de la portée et de la mémoire est perdu.

  5. Assurez-vous que les types correspondent exactement.

    Assurez-vous toujours que les types de pointeurs correspondent au type requis. Ne pas remanier un pointeur sans raison spécifique. Considérez ce qui suit:

fn (int * p) -annuler myFunc () {A'-char * pC char c = '= c-fn ((int *) PC) -}

La fonction ci-dessus compile sans plainte depuis le PC pointeur de caractère a été remanié à un int * pour correspondre à la déclaration de fn (int *) - cependant, ce programme sera presque sûrement pas travailler. La fonction fn () attend un pointeur vers une pleine entier de 32 bits et non pas quelque pacotille 8 bits omble. Ces types de problèmes sont très difficiles à démêler.

Comment et quand faire des copies complètes en C ++

Les classes qui attribuent des ressources de leur constructeur devraient normalement inclure un constructeur de copie pour créer des copies de ces ressources. L'attribution d'un nouveau bloc de mémoire et copier le contenu de l'original dans ce nouveau bloc est connu comme la création d'un copie en profondeur (par opposition à la copie superficielle par défaut). Utilisez les étapes suivantes pour déterminer quand et comment faire des copies profondes en C ++:

  1. Toujours faire une copie en profondeur si le constructeur alloue les ressources.

    Par défaut, C ++ fait soi-disant copies "peu profondes" Membre par membre d'objets lors de leur passage à des fonctions ou à la suite d'une cession. Vous devez remplacer les opérateurs de copie superficielle par défaut avec leur équivalent copie en profondeur pour toute classe qui alloue des ressources dans le constructeur. La ressource la plus commune qui obtient alloué est mémoire de tas qui est renvoyée par le nouvel exploitant.

  2. Toujours inclure un destructeur pour une classe qui alloue les ressources.

    Si vous créez un constructeur qui alloue les ressources, vous devez créer un destructeur qui les restaure. Aucune exception.

  3. Toujours déclarer le destructeur virtuel.

    Une erreur débutant commune est d'oublier de déclarer votre destructeur virtuel. Le programme se déroulera bien jusqu'à un programmeur méfiance arrive et hérite de votre classe. Le programme semble toujours travailler, mais parce que le destructeur de la classe de base ne peut être invoqué correctement, des fuites de mémoire de votre programme comme une passoire jusqu'à ce qu'il se bloque finalement. Ce problème est difficile à trouver.

  4. Toujours inclure un constructeur de copie pour une classe qui alloue les ressources.

    Le constructeur de copie crée une copie correcte de l'objet courant par l'allocation de mémoire hors du tas et copier le contenu de l'objet source.

  5. Toujours remplacer l'opérateur d'affectation pour une classe qui alloue les ressources.

    Les programmeurs devraient être dissuadés de les opérateurs primordiales, mais l'opérateur d'affectation est une exception. Vous devez remplacer l'opérateur d'affectation pour toute classe qui alloue des ressources dans le constructeur.

    L'opérateur d'affectation devrait faire trois choses:

  1. Assurez-vous que l'objet de la main gauche et à droite ne sont pas le même objet. En d'autres termes, être sûr que le programmeur d'application n'a pas écrit quelque chose comme (A = A). Si elles sont, ne rien faire.

  2. Appelez le même code que le destructeur de l'objet de la main gauche pour revenir ses ressources.

  3. Appelez le même code comme un constructeur de copie pour faire une copie profonde de l'objet de la main droite dans l'objet de la main gauche.

  • Si vous ne pouvez pas faire cela, alors supprimer le constructeur de copie et de l'opérateur d'affectation de sorte que le programme ne peut pas faire des copies de votre objet.

  • Si vous ne pouvez même pas le faire parce que votre compilateur ne supporte pas la fonction de suppression constructeur C ++ 2011, créer un constructeur de copie et d'affectation vide et de déclarer les protégeait de garder d'autres classes de leur utilisation.


  • » » » » De commencer la programmation en C ++ pour les nuls