c++ - 在C++中,如何正确获取指向 vector 的共享指针,最大限度地减少复制构造函数的调用次数?

标签 c++ vector constructor shared-ptr copy-constructor

我需要一个函数,它将shared_ptr返回到包含大量对象的 vector 。以下代码实现了这一点,但可以看到复制构造函数被调用了额外的次数。

#include <iostream>
#include <vector>
#include <memory>

using namespace std;

class A {
public:
    int IA ;

    A(int ia) {
        cout << "Constructor is called\n" ;
        IA = ia ;
    }

    A(const A& a) {
        cout << "Copy constructor is called\n" ;
        IA = a.IA ;
    }
} ;


shared_ptr<vector<A>> foo() {

    vector<A> myA ; 

    myA.push_back(A(10)) ;
    myA.push_back(A(20)) ;
    
    return make_shared<vector<A>>(myA) ; 
}



int main() {

    shared_ptr<vector<A>> myA ;
    myA = foo() ;
    
    return 0 ;
}

实际情况下,A也可能更大,所以make_shared<vector<A>>(myA) ; 会导致不必要的复制过程。我想知道是否有什么方法可以减少复制构造函数的调用次数。

最佳答案

您的代码中有两种用法会导致额外的复制。

  1. myA.push_back(A(10))将创建类 A 的临时对象,然后将其复制到 vector myA 中。请注意,我们无法通过更改为 myA.emplace_back(A(10)) 来减少此类重复。 。它还将创建一个临时的 A对象,然后调用 A 的构造函数以临时值 (xvalue) 作为参数。这将调用复制构造函数(因为您没有提供移动构造函数)。

  2. make_shared<vector<A>>(myA)将在 std::shared_ptr 中创建托管对象来自myA ,将被复制。复制 vector 将复制其所有元素。

解决方案:

  1. emplace_back 提供适当的支持。这里我们可以写myA.emplace_back(10) 。现在它将调用 A 的构造函数有参数10 ,这将选择构造函数 A(int) 。即构造类A的对象直接在 vector 中,而不是创建一个临时文件然后将其复制到 vector 中。

  2. 移动myA进入shared_ptr通过make_shared<vector<A>>(std::move(myA)) 。这里它不会复制 vector 中的元素。

请注意,随着 vector 容量的增加,其元素也会被复制。有一些解决方案。如果您知道元素的数量,则可以使用 reserve()预先分配足够的内存。您还可以为类 A 提供 noexcept 移动构造函数。以避免更改容量时复制。

关于c++ - 在C++中,如何正确获取指向 vector 的共享指针,最大限度地减少复制构造函数的调用次数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72713971/

相关文章:

c++ - MFC C++ : TODO <file description> has stopped working

c++ - 如何创建对模板类执行操作的静态模板成员函数?

c# - 关于C#构造函数的问题

java - 为什么 Java Bean 模式不是线程安全的

C++结构,新类型之间的区别;和新类型()

c++ - 声明和带有定义的声明。为什么不允许这样做?

c++ - 如何像 python 语法一样在 C++ 中使用 "cut" vector

javascript - 使用构造函数来构建一次性对象是否有原因?

c++ - 如何在 Autoconf 中使用 C++11 功能?

c++ - C++中 vector 上的未初始化局部变量错误