28 votes

Portée d'une variable initialisée dans la liste des paramètres d'une fonction

Le code suivant se construit, se compile et s'exécute (C++, mingw) apparemment sans aucun problème. Cependant, Ai-je la garantie que les objets construits avec des listes d'initialisation à l'intérieur de la liste des paramètres d'une fonction, vivent dans la portée de cette fonction, même si la fonction prend l'argument par référence ?

Sinon, est-il vrai que lorsque l'on crée un objet en utilisant son initialisateur dans la liste des paramètres d'une fonction (qui prend l'argument par référence), cela peut être dangereux car il sera immédiatement détruit : Dans ce cas, la fonction n'a pas une copie, mais une référence à la mémoire qui peut, ou non, être réallouée par un autre processus ?

struct S
{
  S() : a(0), b(0) {}
  S(int a, int b) : a(a), b(b) {}
  int a;
  int b;
};

void foo(const S& s)
{
  std::cout << "s.a = " << s.a << std::endl;
  std::cout << "s.b = " << s.b << std::endl;
}

int main()
{
  foo({4,5}); // <-- What is the scope of the struct initialized here?

  return 0;
}

14 votes

La portée de l'objet temporaire dure jusqu'à la fin de l'expression complète. Dans votre cas, l'appel de la fonction. Ce qui signifie que le code que vous montrez est correct.

2 votes

Hors sujet : Vous devriez envisager une norme de codage où les noms des paramètres sont différents des noms des membres.

2 votes

Thomas Matthews : Meh, je l'aime comme ça.

37voto

amc176 Points 1379

Selon cppreference [durée de vie] :

Tous les objets temporaires sont détruit comme dernière étape de l'évaluation de l'expression expression complète qui contient (lexicalement) le point où ils ont été créés, et si plusieurs objets temporaires ont été créés, ils sont détruits dans l'ordre opposé à l'ordre de création. Ceci est vrai même si cette évaluation se termine par la levée d'une exception.

Cela signifie que l'objet temporaire sera détruit après la fonction est revenue, donc c'est parfaitement sûr.

7voto

Yola Points 2650

Ici prvalue matérialisé pour créer un objet temporaire de type S de la liste d'initialisation entre crochets {4,5} qui est détruit à la fin de l'expression complète. Dans votre cas foo({4,5}); .

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