C++面试八股-STL(vector)

1.vector原理介绍

        vector是一种内存连续的可动态改变自身存储大小的可变数组,其属于C++标准模板库(standard template library,STL),使用vector需包含头文件<vector.h>。

        vector内的元素,可类似普通数组一样使用下标直接访问,也可以通过迭代器进行访问。迭代器是一种可以访问容器内所有元素的工具,后面再详细介绍。

        vector的容量是可以动态改变的,一般情况下使用vector的步骤是:声明一个vector并指定其元素的数据类型---初始化该vector的容量大小---往该vector增删改查元素---销毁或回收vector内存。在增删改查vector元素的过程中,如果往vector中插入的元素超出了vector的容量(或者达到编译器设置的扩容阈值)时,就会触发vector的扩容操作。vector的扩容操作步骤如下:达到扩容阈值---新开辟一块大小是原vector容量的若干倍的连续内存控件---将原vector的所有数据拷贝至新开辟的内存---让vector指向新的内存---回收原先vector开辟的内存---插入新的元素。从上述步骤可以看到如果频繁触发vector的扩容操作,则会造成显著的时间损耗。

        不同系统设置的扩容系数不一样,Windows是1.5倍,Linux是2倍。

2.常用函数

resize()//改变vector容量1
reserve()//改变vector容量2
assign()//改变vector容量3,同时改变容器中的值
size()//返回返回容器中元素个数
capacity()//返回vector开辟的内存大小
begin()//返回头部迭代器
end()//返回尾部+1迭代器
rbegin()//返回逆首部迭代器
rend()//返回逆尾部-1迭代器
front()//返回首个元素
back()//返回尾部元素
push_back()//在末尾添加一个元素
emplace_back()//和push_back()是一样的作用
pop_back()//弹出最后一个元素
empty()//判断是否为空
insert()//在指定位置插入元素
erase()//在指定位置删除元素
clear()//清空容器

        ①resize()

        有下面两个重载函数

//将容器大小变为n,若n小于当前容器的容量,则n后面的元素全部删除,若n大于当前容器的容量
//则在容器末尾添加n-vec.size()个值,并且将值都设为各数据类型的默认值,例如int为0,std::string为空
void resize(size_type n);

//参数n的含义与上述相同,参数val的作用是在n大于当前容器容量时,在容器末尾添加n-vec,size()个值,
//并且将多出来的值均设置为val,当n小于当前容器容量时,多余的元素会被删除,val无效。
void resize(size_type n, const value_type& val = value_type());

        ②reserve()

        reserve本身不会触发vector对元素的任何操作,同时也不会触发vector元素的构造和析构,所以当调用了reserve,如果此时vector无元素,则size()返回值仍为0。reserve的作用主要是在vector即将添加大量元素时预先申请一块内存,尽可能减少因为频繁插入导致触发扩容操作的次数,以及避免因内存分配或回收导致产生过多的内存碎片。

//开辟一块内存,指明系统应该为这个容器预留多大的空间
//如果在reserve之前vector已经有足够的空间容纳元素了,可能reserve不生效
void reserve(size_type n);

        ③assign()

        assign()用于给vector分配元素,并支持替换当前内容,assign支持接收不同类型的参数,例如:

std::list<int> lst = {1, 2, 3, 4, 5};  
std::vector<int> vec;  
vec.assign(lst.begin(), lst.end());  

        需要注意,极限情况下,在使用assign()函数时,若使用其他容器的迭代器来初始化vector的元素时,如果迭代器的范围超出了vector容器规定的能申请到的最大内存长度max_len

### 常见C++面试问题整理 #### 1. C++语言基础知识 C++是一种多范式的编程语言,它不仅支持面向对象的特性,也保留了许多来自C语言的功能[^1]。因此,在C++中可以找到许多类似于C语言的过程化编程风格。 - **问:为什么说C++不是完全的面向对象语言?** - 答:尽管C++提供了丰富的面向对象功能,但它仍然继承了C语言的部分特征,比如允许使用全局变量和函数等非面向对象的概念[^2]。这使得C++既具有面向对象的优点,又兼容传统的程序设计方法。 #### 2. 关于`this`指针的理解 在C++中,`this`是一个特殊的指针,用于指向当前正在执行操作的对象实例。每当调用某个类的成员函数时,编译器都会自动将对应对象的地址通过`this`参数传入到该函数内部[^3]。 - **问:什么是`this`指针?它的作用是什么?** - 答:`this`是指向当前对象自身的常量指针,主要用于区分同名局部变量与成员变量之间的冲突情况;另外还可以返回当前对象本身或者将其赋值给其他引用/指针以便进一步操作。 - **问:友元函数是否有`this`指针?** - 答:由于友元并不是所属类的一部分而是独立存在的外部实体,所以它们不会接收任何隐含形式的`this`参数。 #### 3. STL容器概述 STL(Standard Template Library)是C++标准库的重要组成部分之一,其中包含了大量通用的数据结构实现——即所谓的“容器”。这些容器能够存储不同类型的数据项并提供高效的操作接口来访问管理这些数据集合。 - **问:常用的几种STL容器有哪些特点区别?** - 答: - `vector`: 动态数组,连续内存分配,随机存取速度快但插入删除较慢; - `list`: 双向链表,节点间无序连接,增删灵活但查找效率低; - `map/set`: 键值映射关系或唯一键集合作为底层红黑树支撑,查询性能稳定O(log n)--- ```cpp #include <iostream> #include <vector> class MyClass { public: void setX(int value) { x = value; } int getX() const { return x; } private: int x; }; int main(){ std::vector<MyClass> vec(5); // 创建大小为5的标准模板库矢量 for(auto& obj : vec){ obj.setX(10); std::cout << "Value of X: " << obj.getX() << "\n"; } return 0; } ``` 上述代码展示了如何利用`std::vector`创建一组自定义类型的对象,并遍历设置其属性值的例子。 --- #### § 1. 如何理解虚函数机制及其应用场景? 2. 深拷贝与浅拷贝的区别在哪里?分别适用于什么场合下? 3. smart pointer 的种类都有哪些? 它们各自解决了传统裸指针存在什么样的安全隐患? 4. 在多线程环境下应该怎样安全地共享资源而不引发竞态条件(race condition)? 5. 如果遇到复杂的继承体系, 能否举例说明钻石继承问题以及解决办法吗 ?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值