[英]In C++, how to correctly obtain a shared pointer to a vector , minimizing the number of copy constructor calling?
我需要一个将 shared_ptr 返回到包含大量对象的向量的函数。 下面的代码实现了这一点,但可以看到复制构造函数被调用了多次。
#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) ;
会导致不必要的复制过程。 我想知道是否有任何方法可以减少复制构造函数的调用时间。
这条线
return make_shared<vector<A>>(myA) ;
正在制作不必要的副本。 您无需先创建向量,然后将其复制到另一个动态分配的向量。 您只需要创建一个向量:
shared_ptr<vector<A>> foo() {
return make_shared<vector<A>>(std::initializer_list<A>{{10},{20}});
}
谢谢! 现在的代码是:
shared_ptr<vector<A>> foo2() {
auto ptr = make_shared<vector<A>>() ;
(*ptr).reserve(99) ;
ptr->emplace_back(A(10)) ;
ptr->emplace_back(A(20)) ;
return ptr ;
}
int main() {
shared_ptr<vector<A>> myA, myA2 ;
myA2 = foo2() ;
cout << (*myA2)[0].IA << endl;
return 0 ;
}
复制构造函数调用的数量减少到两个。 是否可以继续避免调用复制构造函数,因为我认为没有理由在构造后进行复制。
您的代码中有两种用法会导致额外的复制。
myA.push_back(A(10))
将创建一个类A
的临时对象,然后将其复制到向量myA
中。 请注意,我们无法通过更改为myA.emplace_back(A(10))
来减少此类重复。 它还将创建一个临时A
对象,然后以临时 (xvalue) 作为参数调用A
的构造函数。 这将调用复制构造函数(因为您没有提供移动构造函数)。
make_shared<vector<A>>(myA)
将在std::shared_ptr
从myA
创建托管对象,该对象将被复制。 复制向量将复制其所有元素。
解决方案:
为emplace_back
提供适当的参数。 在这里我们可以写myA.emplace_back(10)
。 现在它将使用参数10
调用A
的构造函数,这将选择构造函数A(int)
。 即直接在vector中构造A
类的对象,而不是先创建一个临时的,然后再复制到vector中。
通过make_shared<vector<A>>(std::move(myA))
将myA
移动到shared_ptr
中。 这里它不会复制向量中的元素。
请注意,随着向量容量的增加,它的元素也将被复制。 有一些解决方案。 如果您知道元素的数量,则可以使用reserve()
来预先分配足够的内存。 您还可以为类A
提供一个 noexcept 移动构造函数,以避免在更改容量时复制。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.