47Vector动态数组 in C++
C++的标准库(标准模板库)本质上是一个库,里面装满了容器,容器类型。而之所以被称为标准模板库,因为它可以模板化任何东西。容器包含的数据类型,实际上都由使用者决定,所以东西都由模板组成
vector
是在std命名空间的,也就是说要std::vector
为什么叫vector呢?直接翻译过来就是向量的意思。但其是不应当称为向量,而应当被称为ArrayList,因为他本质上是一个动态数组
如何实现数组数量是动态的呢?原理大概是如果元素数量超出了数组大小,则它会重新创建一个新的更大的数组并把原数组的值都复制过去,然后再把原数组删除
根据上面的原理,其实就可以对vector的底层数据的选择做出优化
- 比如对于一个类对象和一个指向类的指针,是
vector<Entity> ptr
还是vector<Entity*> ptr
呢?技术上应当用对象当数据底层。因为无论是遍历数据还是修改数据,都比较方便 - 💡比如对于字符串和指向字符串的指针,是选
vector<string> vec
ORvector<string*> vec
?如果选string
则在操作的时候其实是对一个字符数组进行操作,如果是进行复制操作,就会特别慢。而如果是指针,则内存分布就不会是直线,而是分散开的分布,这样在读取数据和修改数据或者遍历数据上都很难受
这是个很难的选择,但根据Cherno的经验论:尽量使用对象(而不是指针),指针是最后的无可奈何的选择
顺便一谈vector遍历时需要注意的东西
vector<int> vec(10, 0);
//正经的遍历
for (int i = 0; i < vec.size(); ++i) {
vec[i] = 5;
}
//更加简洁的明了的C++11的遍历
for (int &temp : vec) { //注意这里是引用的形式!不然会多一堆无用的复制副本的操作!而且只有引用了以后才能对vec的元素进行修改!如果不对vec的元素进行修改,则写成 const int &temp : vec 便是了
temp = 5;
}
以及如果想删除一个具体的数,比如下标2的数
vec.erase(2)
❌vec.erase(vec.begin() + 2)
✔- 注意传入的是迭代器!而不是真的把下标传进去了!