Les pièges dans l'ordre décroissant de leur importance
Tout d'abord, vous devriez visiter le primé C++ FAQ de la Lumière. Il a beaucoup de bonnes réponses pour les pièges. Si vous avez d'autres questions, rendez - ##c++
sur irc.freenode.org
dans la CEI. Nous sommes heureux de vous aider, si nous le pouvons. Remarque tous les pièges suivants sont à l'origine écrit. Ils ne sont pas simplement copié à partir de sources aléatoires.
supprimer[]
sur le nouveau, delete
sur new[]
Solution: Faire ci-dessus, les rendements à un comportement indéfini: Tout ce qui pourrait arriver. De comprendre votre code et ce qu'il fait, et toujours delete[]
ce que vous new[]
, et delete
ce que vous new
, alors que ça n'arrivera pas.
Exception:
typedef T type[N]; T * pT = new type; delete[] pT;
Vous avez besoin d' delete[]
même si vous new
, puisque vous les nouvelles ed d'un tableau. Donc, si vous travaillez avec des typedef
, prendre un soin particulier.
L'appel d'une fonction virtuelle dans un constructeur ou un destructeur
Solution: l'Appel d'une fonction virtuelle de ne pas appeler les fonctions de remplacement dans les classes dérivées. L'appel d'une fonction virtuelle pure dans un constructeur ou desctructor est un comportement indéfini.
Appelant delete
ou delete[]
sur un déjà supprimé pointeur
Solution: Affecter 0 à chaque pointeur de vous supprimer. Appelant delete
ou delete[]
sur un pointeur null ne fait rien.
En prenant le sizeof d'un pointeur, lorsque le nombre d'éléments d'un "tableau" est calculée.
Solution: Passer le nombre d'éléments à côté du pointeur lorsque vous avez besoin pour passer un tableau comme un pointeur dans une fonction. Utiliser la fonction proposée ici si vous prenez le sizeof d'un tableau qui est censé pour être vraiment un tableau.
L'utilisation d'un tableau comme s'il s'agissait d'un pointeur. Ainsi, à l'aide de T **
pour les deux dimensions de la matrice.
Solution: Voir ici pour expliquer pourquoi ils sont différents et la façon dont vous les manipulez.
Écriture d'une chaîne de caractères littérale: char * c = "hello"; *c = 'B';
Solution: Allouer un tableau qui est initialisé à partir des données de la chaîne littérale, alors vous pouvez écrire à:
char c[] = "hello"; *c = 'B';
Écriture d'une chaîne de caractères littérale est un comportement indéfini. De toute façon, le ci-dessus, la conversion d'une chaîne littérale char *
est obsolète. Si les compilateurs ne sera probablement avertir si vous augmentez le niveau d'avertissement.
La création de ressources, puis oublier de les libérer quand quelque chose se déclenche.
Solution: Utiliser des pointeurs intelligents comme std::unique_ptr
ou std::shared_ptr
comme l'ont souligné d'autres réponses.
La modification d'un objet deux fois, comme dans cet exemple: i = ++i;
Solution: Le dessus qui était censé affecter à i
la valeur de i+1
. Mais ce qu'il fait n'est pas défini. Au lieu de l'incrémentation i
et l'affectation du résultat, il change i
sur le côté droit. Modification d'un objet entre deux séquence de points est un comportement indéfini. Séquence de points comprennent ||
, &&
, comma-operator
, semicolon
et entering a function
(liste non exhaustive!). Modifiez le code suivant à la faire se comporter correctement: i = i + 1;
Divers Questions
Oublier de rincer les ruisseaux avant d'appeler une fonction de blocage comme sleep
.
Solution: Vider le flux en streaming soit en std::endl
au lieu de \n
ou en appelant stream.flush();
.
La déclaration d'une fonction au lieu d'une variable.
Solution: Le problème se pose parce que le compilateur interprète par exemple
Type t(other_type(value));
en fonction de la déclaration d'une fonction t
de revenir Type
et ayant un paramètre de type other_type
qui est appelé value
. Vous le résoudre en mettant des parenthèses autour du premier argument. Maintenant, vous obtenez une variable t
de type Type
:
Type t((other_type(value)));
L'appel de la fonction d'un objet qui n'est déclaré dans le courant de l'unité de traduction (.cpp
le fichier).
Solution: La norme ne définit pas l'ordre de création des objets libres (à l'espace de noms de champ) définis dans les différentes unités de traduction. L'appel d'une fonction membre d'un objet pas encore construit est un comportement indéfini. Vous pouvez définir la fonction suivante dans l'objet de la traduction de l'unité et de l'appeler à partir d'autres:
House & getTheHouse() { static House h; return h; }
Qui permettrait de créer l'objet de la demande et de vous laisser avec un objet construit au moment de l'appel des fonctions.
La définition d'un modèle dans un sous - .cpp
le fichier, alors qu'il est utilisé dans un autre .cpp
le fichier.
Solution: Presque toujours, vous obtiendrez des erreurs comme undefined reference to ...
. Mettre tous les modèle de définitions dans un en-tête, de sorte que lorsque le compilateur est en les utilisant, il peut déjà produire le code nécessaire.
static_cast<Derived*>(base);
si la base est un pointeur vers une classe de base virtuelle de Derived
.
Solution: Une classe de base virtuelle est une base qui se produit une seule fois, même si elle est héritée plus d'une fois par les différentes classes indirectement dans un arbre d'héritage. Faire ci-dessus n'est pas autorisé par la Norme. Utilisation dynamic_cast pour le faire, et assurez-vous que votre classe de base est polymorphe.
dynamic_cast<Derived*>(ptr_to_base);
si la base est non-polymorphe
Solution: Le standard ne permettent pas à une triste d'un pointeur ou d'une référence lorsque l'objet passé n'est pas polymorphe. Elle ou une de ses classes de base doit avoir une fonction virtuelle.
Faire de votre fonction qui accepte T const **
Solution: on peut penser que c'est plus sûr que d'utiliser T **
, mais en réalité, il provoque des maux de tête aux personnes qui veulent passer T**
: Le standard ne le permet pas. Il donne un exemple clair de pourquoi il est refusé:
int main() {
char const c = 'c';
char* pc;
char const** pcc = &pc; //1: not allowed
*pcc = &c;
*pc = 'C'; //2: modifies a const object
}
Toujours accepter l' T const* const*;
à la place.
Un autre (fermé) pièges thread sur le C++, donc les gens à la recherche pour eux de les trouver, est de Débordement de Pile question C++ pièges.