关于vector使用的优化

 1 class A {
 2 public:
 3     int m_x;
 4 
 5     A(int x)
 6         : m_x(x)
 7     {
 8         std::cout << "A(int )" << std::endl;
 9     }
10     A(const A& a)
11         : m_x(a.m_x)
12     {
13         std::cout << "A(const A&)" << std::endl;
14     }
15 };

 

1 void solve()
2 {
3     std::vector<A > v;
4     v.push_back(A(1));
5     v.push_back(A(2));
6     v.push_back(A(3));
7 }

 

 1 output:
 2 
 3 A(int)
 4 A(const A&)
 5 A(int)
 6 A(const A&)
 7 A(const A&)
 8 A(int)
 9 A(const A&)
10 A(const A&)
11 A(const A&)

对于上述结果 v.push_back(A(i)),进行了三步操作

①A(1) 创建匿名实例

②对于该匿名实例,v中第一块未使用的内存实行" A(const A& a) ",拷贝构造操作

③vector申请的内存是动态改变的,如果 v 执行 push_back操作,发现申请的内存已满,则会申请一块比原先内存大的连续内存,然后依次进行拷贝构造,之后抛弃原先的内存

 

从③可以得知,我们如果知识生气了一个vector,不设置其申请的内存大小,则它会依据压入数据大小动态申请,拷贝,抛弃原先内存的操作,

如果我们得知我们需要大概的 int 个数,则我们可以手动设置vector的大小,防止vector申请内存不够而出现上述情况

1 void solve()
2 {
3     std::vector<A > v;
4     v.reserve(3);
5     //v.resize(3) 是初始化v中存在3个A的实例
6     v.push_back(A(1));
7     v.push_back(A(2));
8     v.push_back(A(3));
9 }

 

1 output:
2 A(int)
3 A(const A&)
4 A(int)
5 A(const A&)
6 A(int)
7 A(const A&)

可以从 output 看出,我们确实优化了vector相关内存和拷贝操作

 

进一步,从①②中可以,我们其实额外申请了内存,然后再对vector的内存对申请的临时的实例拷贝构造,然后丢弃临时实例,这样不省事也不省时

为了解决这个情况,vector 提供了 emplace_back函数,实现直接对vector中对未使用的内存进行初始化构造操作,传入的数值对应于初始化列表或者根据有参构造函数进行操作

 1 void solve()
 2 {
 3     std::vector<A > v;
 4     v.reserve(3);
 5     //v.resize(3) 是初始化v中存在3个A的实例
 6     v.emplace_back(1);
 7     v.emplace_back(2);
 8     v.emplace_back(3);
 9 
10     //for (auto& x : v) std::cout << x.m_x << "  " << x.m_y << std::endl;
11 }
output:
A(int)
A(int)
A(int)

 这样,我们使用vector时,效率会高很多,而且优化也不会很复杂

posted @ 2022-01-20 21:45  SummerMingQAQ  阅读(65)  评论(0编辑  收藏  举报