目录
第三题(unordered_map和priority_queue使用的底层数据结构)
以下关于STL的描述中,()是错的
A STL容器是线程不安全的
B 当容量不够时,STL的一个典型实现是vector内部内存扩展方式为翻倍
C std::sort是稳定排序
D std::bitset不是一个STL容器
A:STL的容器都是线程不安全的。也就是在多线程的情况下,我们需要自己去加锁进行控制
B:有的STL的vector的增长不一定是翻倍
C:sort是一个STL里面的排序算法,它底层是一个插入排序+快速排序构成的。当我们的数据量小于一定的阈值的时候是直接采用插入排序的。如果数据量比较大,采用的是快速排序,也就会导致我们的数据不稳定。
(也就是重复的数据,比方说有3个2,在我们排完之后,我们这3个2之间的顺序发生了变化,就是不稳定)
D:bitset是一个位集合,不是容器
C
STL中的一级容器有:
A vector, deque, list, set, multiset, map, multimap.
B 序列容器,关联容器,容器适配器
C set, multiset, map, multimap.
D vector, deque, list.
STL中的容器是按照序列式容器和关联式容器进行划分的
序列式容器:线性结构
vector list
关联式容器:非线性
map set
一级容器:数据类型不能是组合类型,只能是基本类型
vector<>的<>中可以写int ,double等等
组合类型:
map中必须写值对结构(key-value)(pair)
map
,也就是说我们的map中必须是关键值和实值组成。 set底层是红黑树,红黑树在实现的时候,值类型往往都是一个组合,这个组合往往是通过pair来实现的。
D
STL中的unordered_map和priority_queue使用的底层数据结构分别是什么()
A rbtree,queue
B hashtable,heap
C rbtree,heap
D hashtable,queue
使用到的底层结构:就是适配器
STL中一共有6大组件:空间配置器、容器、算法、迭代器、仿函数、适配器
适配器主要有:
栈和队列是通过双端队列实现的(deque)
优先级队列是通过vector去进行实现的,因为它经常需要被访问
map和set底层是通过红黑树去进行实现的rbtree(严格来说,这里不是适配器,因为底层是用红黑树直接写死的,不能更改的)
unordered_set(hash_map)和unordered_set(hash_set)它们的底层的实现结构都是hashtable,也就是哈希表来实现的
所以按照我们上面的说法,我们的unordered_map的底层是通过hash_map来实现的,而我们的priority_queue是通过vector实现的,但是这个vector想要实现的是一个堆,并且是一个大根堆(默认)
B
下面关于迭代器失效的描述哪个是错误的()
A vector的插入操作不会导致迭代器失效
B map的插入操作不会导致迭代器失效
C vector的删除操作只会导致指向被删除元素及后面的迭代器失效
D map的删除操作只会导致指向被删除元素的迭代器失效
迭代器失效:
插入数据(扩容)
删除数据(数据移动)
(原来的迭代器所指向的空间位置无效了,就是迭代器失效)
A:会导致迭代器失效,因为我们在插入的时候,万一我们的vector发生了扩容,重新malloc了一块地址,我们的迭代器就失效了
B:正确
C:因为向量在删除某一个数据之后,后面的数据会往前移动,那么我们所指向的位置以及后面的元素就有可能失效了。
D:我们删除了当前的结点,那么当前节点的迭代器肯定失效。
A
如何捕获异常可以使得代码通过编译?
- class A {
- public:
- A(){}
- };
- void foo(){
- throw new A;
- }
A catch (A && x)
B catch (A * x)
C catch (A & x)
D 以上都是
这里我们new了一个对象A,也就是返回一个A类型的地址,所以我们需要接收A的类型的指针类型,也就是catch(A *x)
B
- #include
- using namespace std;
- class A {
- public:
- ~A() {
- cout << "~A()";
- }
- };
- class B{
- public:
- virtual ~B() {
- cout << "~B()";
- } }
- ;
- class C: public A, public B {
- public:
- ~C() {
- cout << "~C()";
- }
- };
- int main() {
- C * c = new C;
- B * b1 = dynamic_cast(c);
- A * a2 = dynamic_cast(b1);
- delete a2;
- }
A ~C()~B()~A()
B ~C()~A()~B()
C A)B)都有可能
D 以上都不对
A与B没有关系,C同时继承了A和B
然后创建一个子类的指针c指向子类的对象C
然后创建一个父类的指针b1去接收c
然后将b1强行转换给a类指针a2,但是我们的A和B两类之间并没有任何关系
但是我们在释放a2,也就是释放a所指向的空间,也就是我们想要去释放子类c中的空间。
因为动态转换之后,会导致它的释放指向子类,
但是由于我们的A类和B类之间没有任何关系,所以在释放A类的时候会导致程序崩溃。
D