📜  C++ STL向量中的push_back()vs emplace_back()

📅  最后修改于: 2021-05-30 19:52:38             🧑  作者: Mango

在C++中,向量是动态数组,可以增长或收缩,它们的存储由容器本身处理。有两种在向量中插入元素的方法。它们是push_back()emplace_back() 。在本文中,我们将讨论它们之间的区别。

push_back()

此方法用于从容器的末端将元素插入向量中。由于向量大小的灵活性是动态的,因此在插入任何新元素后,容器的大小也会增加1。

程序1:

C++
// C++ program to demonstrate the
// push_back() method
  
#include 
#include 
  
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()
{
    // Vector of object of GFG class
    // is created
    vector vertices;
  
    // Inserting elements in the object
    // created using push_back() method
  
    // Custom input entries
    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;
}


C++
// C++ Program to demonstrate the
// reserve() method with the
// push_back() method
  
#include 
#include 
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 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;
}


C++
// C++ Program to illustrate the high
// cost of copying the elements in
// vector in STL
  
#include 
#include 
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 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;
}


C++
// C++ program to optimize the usage
// of C++ Vectors to reduce the cost
// of copying elements
  
#include 
  
using namespace std;
  
// Class
class GFG {
  
public:
    float x, y;
  
    // Parametrised 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
    vector vertices;
  
    // Reserve few elements in the
    // vector using reserve() method
    vertices.reserve(3);
  
    // Add elements to the object of
    // vector class
    vertices.push_back(GFG(1, 2));
    vertices.push_back(GFG(4, 5));
    vertices.push_back(GFG(7, 8));
  
    return 0;
}


输出:
Copied

Copied
Copied

Copied
Copied
Copied

解释:

  • 在主函数,创建大小为1的GFG类向量。在将第一个GFG对象插入数组之前,使用参数化构造函数创建该对象,并且由于向量为GFG类型,因此该对象将传递给“ GFG ”副本构造函数,因此“ Copied ”将被打印一次。但是,当要插入另一个元素时,会创建一个新的向量,该向量的大小大于前一个向量,然后再次复制“第一个”元素,然后创建并复制第二个对象,因此“复制”被打印两次,执行后。
  • 类似地,当要创建第三个对象时,将在内存中分配更大的新矢量,先复制第一个元素,然后复制第二个元素,然后再复制第三个元素。因此,对于复制的构造函数称为“三次”,“ Copied ”被打印三次,对于每个插入的元素一次。
  • 但是,如果向量的大小是固定的,则在插入任何元素之前,将打印“已复制”的次数为3。这是因为声明了所需的大小后,每次插入都不会进行元素的重新复制。

注意:使用reserve()代替使用“ vector vertices(3)” ,因为以下语法有时不起作用,因为该类中没有定义默认构造函数。

"vector vertices(3);”

程式2:

C++

// C++ Program to demonstrate the
// reserve() method with the
// push_back() method
  
#include 
#include 
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 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;
}
输出:
Copied

Copied

Copied

emplace_back()

使用此方法,而不是使用参数化的构造函数创建对象并将其分配到其他内存中,然后将其传递给复制构造函数,后者会将其插入向量中。该函数可以直接插入对象,而无需调用复制构造函数。下面是说明相同内容的程序:

程序3:

C++

// C++ Program to illustrate the high
// cost of copying the elements in
// vector in STL
  
#include 
#include 
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 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;
}
输出:

说明:在上述程序中,由于使用emplace_back()函数时不会进行构造函数的复制,因此不会打印任何内容。由于复制元素而导致的成本很高。

计划4:

下面是优化C++ Vector用法以减少复制元素成本的程序:

C++

// C++ program to optimize the usage
// of C++ Vectors to reduce the cost
// of copying elements
  
#include 
  
using namespace std;
  
// Class
class GFG {
  
public:
    float x, y;
  
    // Parametrised 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
    vector vertices;
  
    // Reserve few elements in the
    // vector using reserve() method
    vertices.reserve(3);
  
    // Add elements to the object of
    // vector class
    vertices.push_back(GFG(1, 2));
    vertices.push_back(GFG(4, 5));
    vertices.push_back(GFG(7, 8));
  
    return 0;
}
输出:
Copied
Copied
Copied
要从最佳影片策划和实践问题去学习,检查了C++基础课程为基础,以先进的C++和C++ STL课程基础加上STL。要完成从学习语言到DS Algo等的更多准备工作,请参阅“完整面试准备课程”