web-dev-qa-db-fra.com

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?

122
httpinterpret

Si vous placez la déclaration dans un fichier d'en-tête et la définition dans un fichier .cpp fichier et #include l'en-tête d'un autre .cpp fichier, vous pourrez voir la différence.

Spécifiquement, supposons:

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 test.cpp ne verra pas la déclaration de paramètre par défaut et échouera avec une erreur.

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

lib.h

int Add(int a, int b = 3);
190
Greg Hewgill

En C++, les exigences imposées aux arguments par défaut en ce qui concerne leur emplacement dans la liste de paramètres sont les suivantes:

  1. L'argument par défaut pour un paramètre donné ne doit pas ê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 avec des arguments par défaut doivent former un groupe contigu à la fin de la liste des paramètres.

Maintenant, gardez cela à l'esprit, en C++, vous êtes autorisé à "agrandir" l'ensemble de paramètres qui ont des arguments par défaut d'une déclaration de la fonction à la suivante, à condition que les exigences ci-dessus soient toujours satisfaites.

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

void foo(int a, int b);

Pour appeler cette fonction après une telle déclaration, vous devez spécifier explicitement les deux arguments.

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

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

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

Plus bas, vous pouvez le déclarer à nouveau en ajoutant un argument supplémentaire par défaut

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

et à partir de là, vous pouvez l'appeler sans arguments explicites.

L'exemple complet pourrait ressembler à ceci

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)
{
  // ...
}

En ce qui concerne le code dans votre question, les deux variantes sont parfaitement valables, mais elles signifient différentes choses. La première variante déclare immédiatement un argument par défaut pour le second paramètre. La deuxième variante déclare initialement votre fonction sans arguments par défaut, puis en ajoute un pour le deuxième paramètre.

L’effet net de vos deux déclarations (c’est-à-dire la manière dont il est vu par le code qui suit la deuxième déclaration) est exactement le même: la fonction a un argument par défaut pour son deuxième paramètre. Toutefois, si vous parvenez à insérer du code entre la première et la deuxième déclaration, ces deux variantes se comporteront différemment. Dans la deuxième variante, la fonction n'a pas d'argument par défaut entre les déclarations, vous devez donc spécifier explicitement les deux arguments.

43
AnT

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.

Dans le deuxième cas, il n’ya aucune garantie de 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é.

5
user342264

Les arguments par défaut doivent être spécifiés avec la première occurrence du nom de la fonction, généralement dans le prototype de la 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.

4
clyfe