146 votes

Valeur par défaut du paramètre de fonction

1.

 int Add (int a, int b = 3);
int Add (int a, int b)
{

}
 

2

 int Add (int a, int b);
int Add (int a, int b = 3)
{

}
 

Les deux fonctionnent, quelle est la méthode standard et pourquoi ?

219voto

Greg Hewgill Points 356191

Si vous mettez la déclaration dans un fichier d'en-tête, et la définition dans un distinct .cpp le fichier, et #include l'en-tête à partir d'un autre .cpp le fichier, vous serez en mesure de voir la différence.

Plus précisément, supposons que:

lib.h

int Add(int a, int b);

lib.cpp

int Add(int a, int b = 3) {
   ...
}

test.cpp

#include "lib.h"

int main() {
    Add(4);
}

La compilation de l' test.cpp ne verrez pas le paramètre par défaut de déclaration, et échouera avec une erreur.

Pour cette raison, le paramètre par défaut de définition est généralement spécifiée dans la fonction de déclaration:

lib.h

int Add(int a, int b = 3);

45voto

AndreyT Points 139512

En C++ les exigences imposées sur des arguments par défaut par rapport à leur emplacement dans la liste des paramètres sont comme suit:

  1. L'argument par défaut pour un paramètre donné, doit être spécifié plus d'une fois. Spécifier plus d'une fois (même avec la même valeur par défaut) est illégal.

  2. Les paramètres par défaut des arguments pour former un groupe contigu à la fin de la liste des paramètres.

Maintenant, en gardant cela à l'esprit, en C++, vous êtes autorisé à "grandir", l'ensemble de paramètres qui ont des arguments par défaut d'une déclaration de la fonction à l'autre, aussi longtemps que les exigences ci-dessus sont constamment remplies.

Par exemple, vous pouvez déclarer une fonction sans arguments par défaut

void foo(int a, int b);

Pour appeler cette fonction après une telle déclaration, vous aurez à spécifier à la fois les arguments explicitement.

Plus tard, vous pouvez le déclarer à nouveau dans la même unité de traduction, mais cette fois avec un argument par défaut

void foo(int a, int b = 5);

et à partir de ce point, vous pouvez l'appeler avec un seul argument explicite.

Plus bas, vous pouvez redeclare il encore que l'ajout d'un argument par défaut

void foo(int a = 1, int b);

et à partir de ce point, vous pouvez l'appeler avec n'explicite les arguments.

L'exemple complet peut se présenter comme suit

void foo(int a, int b);

int main()
{
  foo(2, 3);

  void foo(int a, int b = 5); // redeclare
  foo(8); // OK, calls `foo(8, 5)`

  void foo(int a = 1, int b); // redeclare again
  foo(); // OK, calls `foo(1, 5)`
}

void foo(int a, int b)
{
  // ...
}

Comme pour le code dans votre question, les deux variantes sont parfaitement valables, mais ils signifient des choses différentes. La première variante déclare un argument par défaut pour le deuxième paramètre. La deuxième variante d'abord déclare votre fonction sans arguments par défaut, puis ajoute un pour le deuxième paramètre.

L'effet net de vos deux déclarations (c'est à dire la façon dont il est vu par le code qui suit la deuxième déclaration) est exactement le même: la fonction a défaut d'argument pour sa deuxième paramètre. Toutefois, si vous parvenez à le presser un peu de code entre la première et la seconde déclarations, ces deux variantes se comportent différemment. Dans la seconde variante, la fonction n'a pas d'arguments par défaut entre les déclarations, de sorte que vous aurez à spécifier à la fois les arguments explicitement.

5voto

user342264 Points 1

Le premier moyen serait préféré au second.

En effet, le fichier d'en-tête montrera que le paramètre est facultatif et quelle sera sa valeur par défaut. De plus, cela garantira que la valeur par défaut sera la même, quelle que soit l'implémentation du fichier .cpp correspondant.

De la deuxième manière, il n’ya aucune garantie d’une valeur par défaut pour le deuxième paramètre. La valeur par défaut peut varier en fonction de la manière dont le fichier .cpp correspondant est implémenté.

4voto

clyfe Points 15388

Les arguments par défaut doivent être spécifiés avec la première occurrence de la fonction name, généralement dans le prototype de fonction. Si le prototype de fonction est omis car la définition de la fonction sert également de prototype, les arguments par défaut doivent être spécifiés dans l'en-tête de la fonction.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X