push_back() vs emplace_back() en vectores STL de C++

En C++ , los vectores son arrays dinámicas , que pueden crecer o reducirse y su almacenamiento lo maneja el propio contenedor . Hay dos formas de insertar un elemento en un vector . Son push_back() y emplace_back() . En este artículo, discutiremos la diferencia entre ellos.

retroceder() :

Este método se utiliza para insertar elementos en un vector desde el final del contenedor. Como la flexibilidad en el tamaño del vector es dinámica, el tamaño del contenedor también aumenta en 1 después de insertar cualquier elemento nuevo.

Programa 1:

C++

// C++ program to demonstrate the
// push_back() method
 
#include <iostream>
#include <vector>
 
using namespace std;
 
// Class
class GFG {
 
public:
    int x;
 
    // Parameterized Constructor
    GFG(int x)
        : x(x)
    {
        cout << "Constructor=>"
             << "x:" << x << endl;
    }
 
    // Copy Constructor
    GFG(const GFG& GFG)
        : x(GFG.x)
    {
        cout << "Copied=>"
             << "x:" << x << endl;
    }
 
    ~GFG()
    {
        cout << "destructor=>"
             << "x:" << x << endl;
    }
};
 
// Driver Code
int main()
{
    // Vector of object of GFG class
    // is created
    vector<GFG> vertices;
    cout << "length of vertices:" << vertices.size()
         << endl;
 
    // Inserting elements in the object
    // created using push_back() method
    cout << endl;
    // Custom input entries
    vertices.push_back(GFG(1));
    cout << endl;
 
    vertices.push_back(GFG(11));
    cout << endl;
 
    vertices.push_back(GFG(21));
    cout << endl;
 
    return 0;
}
Producción

length of vertices:0

Constructor=>x:1
Copied=>x:1
destructor=>x:1

Constructor=>x:11
Copied=>x:11
Copied=>x:1
destructor=>x:1
destructor=>x:11

Constructor=>x:21
Copied=>x:21
Copied=>x:1
Copied=>x:11
destructor=>x:1
destructor=>x:11
destructor=>x:21

destructor=>x:1
destructor=>x:11
destructor=>x:21

Explicación:

  • Cada vez que retroceda un valor a un vector, cpp creará un nuevo vector que copiará el nuevo valor del parámetro y todos los valores en el vector anterior 
  • En la función principal, se crea un vector (vector1) de clase GFG de tamaño 0 . Cuando se usa GFG(int) como parámetro, se crea usando un constructor parametrizado , y dado que el vector es de tipo GFG, el objeto se pasa al constructor de copia » GFG «, por lo tanto, » Copiado » se imprime una vez. 
  • Cuando el segundo valor GFG se haya empujado _back , se creará un nuevo vector (vector2) con mayor tamaño y se copiará el GFG (11) en él. Y luego todos los valores en el viejo vector que se refiere al vector1{1} Copiado al Vector2, por lo que el » Copiado » se imprime dos veces cuando el segundo GFG ha sido retrocedido.
  • De manera similar, cuando se va a crear el tercer objeto, se asigna un nuevo vector de mayor tamaño en la memoria , se copia el primer elemento, luego se copia el segundo elemento y luego se copia el tercer elemento. Por lo tanto, » Copiado » se imprime tres veces, ya que el constructor de copias se llama tres veces, una vez para cada elemento insertado.
  • Sin embargo, si el tamaño del vector es fijo, entonces antes de insertar cualquier elemento, la cantidad de veces que se imprimirá «Copiado» es una. Esto se debe a que, como se declara el tamaño requerido, no se vuelve a copiar los elementos en cada inserción.

Nota: reserve() se usa en lugar de usar “vector<Point> vertices(3)” , ya que la siguiente sintaxis a veces no funciona porque no hay un constructor predeterminado definido en la clase.

"vector<GFG> vertices(3);”

Programa 2:
El costo por la copia de elementos es alto. A continuación se muestra el programa para optimizar el uso de vectores C++ para reducir el costo de copiar elementos:

C++

// C++ Program to optimize the usage
// of C++ Vectors to reduce the cost
// of copying elements with the
// reserve() method
 
#include <iostream>
#include <vector>
using namespace std;
 
// Class
class GFG {
 
public:
    float x, y;
 
    // Parameterized Constructor
    GFG(float x, float y)
        : x(x), y(y)
    {
    }
 
    // Copy Constructor
    GFG(const GFG& GFG)
        : x(GFG.x), y(GFG.y)
    {
        cout << "Copied" << endl;
    }
};
 
// Driver Code
int main()
{
    // Create object of vector in
    // the main() method
    vector<GFG> vertices;
 
    // Reserve three elements using
    // reserve()
    vertices.reserve(3);
 
    // Add elements to the vector
    // object
    vertices.push_back(GFG(1, 2));
    cout << endl;
 
    vertices.push_back(GFG(4, 5));
    cout << endl;
 
    vertices.push_back(GFG(7, 8));
    cout << endl;
 
    return 0;
}
Producción: 

Copied

Copied

Copied

 

emplace_back() :

Este método se usa en lugar de crear el objeto usando un constructor parametrizado y asignarlo a una memoria diferente, luego pasarlo al constructor de copia , que lo insertará en el vector . Esta función puede insertar directamente el objeto sin llamar al constructor de copias . A continuación se muestra el programa para ilustrar lo mismo:

Programa 3:

C++

// C++ Program to illustrate the high
// cost of copying the elements in
// vector in STL
 
#include <iostream>
#include <vector>
using namespace std;
 
// Class
class GFG {
 
public:
    float x, y;
 
    // Parameterized Constructor
    GFG(float x, float y)
        : x(x), y(y)
    {
    }
 
    // Copy Constructor
    GFG(const GFG& GFG)
        : x(GFG.x), y(GFG.y)
    {
        cout << "Copied" << endl;
    }
};
 
// Driver Code
int main()
{
    // Create an object of vector
    // class object
    vector<GFG> vertices;
 
    // Reserve the elements in the
    // vector using reserve() method
    vertices.reserve(3);
 
    // Add element to vector object
    // using emplace_back() method
    vertices.emplace_back(1, 2);
    cout << endl;
 
    vertices.emplace_back(4, 5);
    cout << endl;
 
    vertices.emplace_back(7, 8);
    cout << endl;
 
    return 0;
}
Producción: 

 

 

Explicación: En el programa anterior no se imprime nada ya que la copia del constructor no se realiza mientras se utiliza la función emplace_back()

Veamos la diferencia entre en forma tabular -:

  Hacer retroceder emplace_back
1. Se utiliza para insertar el elemento en un vector o una string Se utiliza para insertar un elemento en un vector o una string.
2. es mas lento Es mas rapido.
3.

Su sintaxis es:

push_back(valor_a_insertar)

Su sintaxis es -:

emplace_back(valor_a_insertar)

4. push_back acepta el único objeto del tipo si el constructor acepta más de un argumento emplace_back acepta argumentos del constructor del tipo.

Publicación traducida automáticamente

Artículo escrito por mabhishek1002 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *