push_back vs emplace_back : quelle est la différence et que choisir pour un débutant ?

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Introduction : pourquoi est-ce important ?

\n\n

Avez-vous déjà réfléchi à la raison pour laquelle il existe deux façons d'ajouter un élément à la fin d'un vecteur en C++ ? Apparemment, pourquoi réinventer la roue alors qu'il existe le push_back éprouvé ? La réponse réside dans les performances et la flexibilité du C++ moderne.

\n\n

Sur Stack Overflow, cette question a recueilli des milliers de vues et des centaines de commentaires. Et ce n'est pas un hasard : comprendre la différence entre push_back et emplace_back n'est pas seulement une connaissance académique, mais une compétence pratique qui peut accélérer votre code de 2 à 3 fois. Décortiquons cela une fois pour toutes.

\n\n

Différence fondamentale : que disent les documentations ?

\n\n

Commençons par le simple. Les deux méthodes ajoutent un élément à la fin du conteneur (vecteur, liste, file d'attente). Mais elles le font différemment :

\n\n
    \n
  • push_back — prend un objet prêt (par valeur, référence ou référence rvalue) et le copie/déplace dans le conteneur.
  • \n
  • emplace_back — prend les arguments du constructeur de l'objet et le crée directement à l'intérieur du conteneur (construction in-place).
  • \n
\n\n

Cela semble abstrait ? Regardons le code.

\n\n

Exemple pratique : création d'une classe

\n\n

Imaginons que nous ayons une classe simple Person :

\n\n
#include <iostream>\n#include <vector>\n#include <string>\n\nclass Person {\npublic:\n    std::string name;\n    int age;\n\n    // Constructeur\n    Person(const std::string& n, int a) \n        : name(n), age(a) {\n        std::cout << "Constructeur appelé pour " << name << std::endl;\n    }\n\n    // Constructeur de copie\n    Person(const Person& other) \n        : name(other.name), age(other.age) {\n        std::cout << "Constructeur de copie pour " << name << std::endl;\n    }\n\n    // Constructeur de déplacement\n    Person(Person&& other) noexcept\n        : name(std::move(other.name)), age(other.age) {\n        std::cout << "Constructeur de déplacement pour " << name << std::endl;\n    }\n};
\n\n

Voyons maintenant ce qui se passe avec différentes méthodes.

\n\n

Option 1 : push_back avec un objet temporaire

\n\n
int main() {\n    std::vector<Person> people;\n    people.push_back(Person("Alice", 25));\n    return 0;\n}
\n\n

Sortie :

\n
Constructeur appelé pour Alice\nConstructeur de déplacement pour Alice
\n\n

Que s'est-il passé ? D'abord, un objet temporaire Person est créé (premier appel au constructeur). Ensuite, cet objet est déplacé dans le vecteur (constructeur de déplacement). Deux appels — double travail.

\n\n

Option 2 : push_back avec un objet prêt

\n\n
int main() {\n    std::vector<Person> people;\n    Person alice("Alice", 25);\n    people.push_back(alice);  // alice — lvalue\n    return 0;\n}
\n\n

Sortie :

\n
Constructeur appelé pour Alice\nConstructeur de copie pour Alice
\n\n

Ici, nous voyons une copie, et non un déplacement. Si l'objet est volumineux (contenant par exemple des tableaux dynamiques), la copie peut être coûteuse.

\n\n

Option 3 : emplace_back

\n\n
int main() {\n    std::vector<Person> people;\n    people.emplace_back("Bob", 30);  // On passe les arguments du constructeur\n    return 0;\n}
\n\n

Sortie :

\n
Constructeur appelé pour Bob
\n\n

Un seul appel au constructeur ! L'objet Person est créé directement dans la mémoire du vecteur, sans copies ou déplacements intermédiaires.

\n\n

Performances : quand la différence est-elle critique ?

\n\n

Pour les types simples (int, double, pointeurs), la différence est imperceptible — le compilateur optimise tout. Mais pour les objets complexes, la différence peut être significative :

\n\n
    \n
  • Objets avec un constructeur de copie lourd (par exemple, std::string, conteneu

Blogs

Book Recommendations