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

📅  最后修改于: 2021-09-14 01:23:31             🧑  作者: Mango

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

push_back()

此方法用于从容器的末尾向向量中插入元素。由于向量大小的灵活性是动态的,因此插入任何新元素后,容器的大小也会增加 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 optimize the usage
// of C++ Vectors to reduce the cost
// of copying elements with the
// reserve() 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;
}


输出:
Copied

Copied
Copied

Copied
Copied
Copied

解释:

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

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

"vector vertices(3);”

方案二:
由于复制元素而导致的成本很高。下面是优化C++ Vectors的使用以减少复制元素的成本的程序:

C++

// C++ Program to optimize the usage
// of C++ Vectors to reduce the cost
// of copying elements with the
// reserve() 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() :

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

方案三:

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()函数时不会发生构造函数的复制。

想要从精选的视频和练习题中学习,请查看C++ 基础课程,从基础到高级 C++ 和C++ STL 课程,了解基础加 STL。要完成从学习语言到 DS Algo 等的准备工作,请参阅完整的面试准备课程