Les arguments par défaut Examinez les deux constructeurs de Stash() dans Stash3.h. Ils ne semblent pas si différents, n'est-ce pas ? En fait, le premier constructeur semble être un cas spécial du second avec la taille (size) initiale réglée à zéro. C'est un peu un gaspillage d'efforts de créer et de maintenir deux versions différentes d'une fonction semblable. C++ fournit un remède avec les arguments par défaut. Un argument par défaut est une valeur donnée dans la déclaration que le compilateur insère automatiquement si vous ne fournissez pas de valeur dans l'appel de fonction. Dans l'exemple Stash(), nous pouvons remplacer les deux fonctions : Stash(int size); // Quantitée zéro Stash(int size, int initQuantity); par la seule fonction : Stash(int size, int initQuantity = 0); La définition de Stash(int) est simplement enlevée -tout ce qui est nécessaire est la définition unique Stash(int,int). Maintenant, les deux définitions d'objet : Stash A(100), B(100, 0); Produiront exactement les mêmes résultats. Le même constructeur est appelé dans les deux cas, mais pour A, le deuxième argument est automatiquement substitué par le compilateur quand il voit que le premier argument est un int et qu'il n'y a pas de second argument. Le compilateur a vu l'argument par défaut, ainsi il sait qu'il peut toujours faire l'appel à la fonction s'il substitue ce deuxième argument, ce qui est ce que vous lui avez dit de faire en lui donnant une valeur par défaut. Les arguments par défaut sont une commodité, comme la surcharge de fonction est une commodité. Les deux dispositifs vous permettent d'employer un seul nom de fonction dans différentes situations. La différence est qu'avec des arguments par défaut le compilateur ajoute les arguments quand vous ne voulez pas mettre vous-même. L'exemple précédent est un cas idéal pour employer des arguments par défaut au lieu de la surcharge de fonction ; autrement vous vous retrouvez avec deux fonctions ou plus qui ont des signatures semblables et des comportements semblables. Si les fonctions ont des comportements très différents, il n'est généralement pas logique d'employer des arguments par défaut (du reste, vous pourriez vous demander si deux fonctions avec des comportements très différents doivent avoir le même nom). Il y a deux règles que vous devez prendre en compte quand vous utilisez des arguments par défaut. En premier lieu, seul les derniers arguments peuvent être mis par défauts. C'est-à-dire que vous ne pouvez pas faire suivre un argument par défaut par un argument qui ne l'est pas. En second lieu, une fois que vous commencez à employer des arguments par défaut dans un appel de fonction particulier, tous les arguments suivants dans la liste des arguments de cette fonction doivent être par défaut (ceci dérive de la première règle). Les arguments par défaut sont seulement placés dans la déclaration d'une fonction (typiquement placée dans un fichier d'en-tête). Le compilateur doit voir la valeur par défaut avant qu'il puisse l'employer. Parfois les gens placeront les valeurs commentées des arguments par défaut dans la définition de fonction, pour des raisons de documentation. void fn(int x /* = 0 */) { // ... Paramètre fictif Les arguments dans une déclaration de fonction peuvent être déclarés sans identifiants. Quand ceux-ci sont employés avec des arguments par défaut, cela peut avoir l'air un peu bizarre. Vous pouvez vous retrouver avec : void f(int x, int = 0, float = 1.1); En C++ vous n'avez pas besoin des identifiants dans la définition de fonction, non plus : void f(int x, int, float flt) { /* ... */ } Dans le corps de la fonction, on peut faire référence à x et flt, mais pas à l'argument du milieu, parce qu'il n'a aucun nom. Cependant, les appels de fonction doivent toujours fournir une valeur pour le paramètre fictif : f(1) ou f(1.2.3.0). Cette syntaxe permet de passer l'argument comme un paramètre fictif sans l'utiliser. L'idée est que vous pourriez vouloir changer la définition de la fonction pour employer le paramètre fictif plus tard, sans changer le code partout où la fonction est appelée. Naturellement,vous pouvez accomplir la même chose en employant un argument nommé, mais si vous définissez l'argument pour le corps de fonction sans l'employer, la plupart des compilateurs vous donneront un message d'avertissement, supposant que vous avez fait une erreur logique. En omettant intentionnellement le nom d'argument, vous faite disparaître cet avertissement. Plus important, si vous commencez à employer un argument de fonction et décidez plus tard que vous n'en avez pas besoin, vous pouvez effectivement l'enlever sans générer d'avertissements, et sans pour autant déranger de code client qui appelait la version précédente de la fonction.