1.vector中空间不够会发生什么?
vector会重新分配新的内存,分配一块新内存,将旧内存中数据复制到新内存,然后释放旧内存。
2,复制是在什么时候发生的?
#include <iostream>
#include <vector>
class Demo
{
public:
int x, y;
Demo(int _x,int _y):x(_x),y(_y){}
~Demo(){}
Demo(const Demo& other)
{
std::cout << "copy!" << std::endl;
}
};
int main()
{
std::vector<Demo> demos;
demos.push_back(Demo(1, 2));
demos.push_back(Demo(3, 4));
demos.push_back(Demo(5, 6));
}
//结果
copy!
copy!
copy!
copy!
copy!
copy!
我们通过断点的方式发现,在main()函数运行第二行后发生了第一次拷贝,运行第三行后又发生了两次拷贝,运行第四行后又发生了三次拷贝。这是vector进行了三次扩容。
如何优化?
1.预估大小,避免扩容
int main()
{
std::vector<Demo> demos;
demo.reserve(3);
demos.push_back(Demo(1, 2));
demos.push_back(Demo(3, 4));
demos.push_back(Demo(5, 6));
}
//结果
copy!
copy!
copy!
为什么还有三次拷贝,这是因为我们先通过构造函数Demo(1,2)构造了一个对象,然后复制到vector中的。
int main()
{
std::vector<Demo> demos;
demo.reserve(3);
demos.emplace_back(1, 2);
demos.emplace_back(3, 4);
demos.emplace_back(5, 6);
}
//结果:
//不会打印任何东西
emplace_back(),会根据传入的参数直接构造一个给定类型的对象。所以不会产生拷贝。
3.遍历,删除
#include <iostream>
#include <vector>
#include <algorithm> // for_each
class Demo
{
public:
int x, y;
Demo(int _x,int _y):x(_x),y(_y){}
~Demo(){}
Demo(const Demo& other)
{
std::cout << "copy!" << std::endl;
}
};
void PrintDemo(const Demo& demo)
{
std::cout << demo.x << demo.y << std::endl;
}
int main()
{
std::vector<Demo> demos;
demos.reserve(3);
demos.emplace_back(1,2);
demos.emplace_back(3, 4);
demos.emplace_back(5, 6);
for (const Demo& let : demos)
{
std::cout << let.x << let.y << std::endl;
}
//迭代器遍历
for (auto iter = demos.begin(); iter!= demos.end();iter++)
{
std::cout<< iter->x << iter->y << std::endl;
}
//标准库函数
std::for_each(demos.begin(), demos.end(), PrintDemo);
}
//删除
#include <iostream>
#include <vector>
class Demo
{
public:
int x, y;
Demo(int _x,int _y):x(_x),y(_y){}
~Demo(){}
Demo(const Demo& other)
{
std::cout << "copy!" << std::endl;
}
};
int main()
{
std::vector<Demo> demos;
demos.reserve(3);
demos.emplace_back(1,2);
demos.emplace_back(3, 4);
demos.emplace_back(5, 6);
demos.pop_back();//删除末尾元素
//迭代器遍删除
for (auto iter = demos.begin(); iter != demos.end();)
{
if (iter->x ==3)
{
iter = demos.erase(iter);
}
iter++;
}
}