我需要一个函数,它将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) ;
会导致不必要的复制过程。我想知道是否有什么方法可以减少复制构造函数的调用次数。
最佳答案
您的代码中有两种用法会导致额外的复制。
myA.push_back(A(10))
将创建类A
的临时对象,然后将其复制到 vectormyA
中。请注意,我们无法通过更改为myA.emplace_back(A(10))
来减少此类重复。 。它还将创建一个临时的A
对象,然后调用A
的构造函数以临时值 (xvalue) 作为参数。这将调用复制构造函数(因为您没有提供移动构造函数)。make_shared<vector<A>>(myA)
将在std::shared_ptr
中创建托管对象来自myA
,将被复制。复制 vector 将复制其所有元素。
解决方案:
为
emplace_back
提供适当的支持。这里我们可以写myA.emplace_back(10)
。现在它将调用A
的构造函数有参数10
,这将选择构造函数A(int)
。即构造类A
的对象直接在 vector 中,而不是创建一个临时文件然后将其复制到 vector 中。移动
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/