C++:STL中的细节问题(1)

/ C++ / 没有评论 / 290浏览

C++:STL中的细节问题

  1. std::vector清空元素后,内存中还存在嘛?

    答:存在,使用内置方法clear和遍历erase是一样的,想要清楚元素和回收内存,应该使用swap,交换之后原vector就自动析构了。

  2. erase迭代器失效问题

    答:std::vector情况有三种:在push_back的时候 end()操作返回的迭代器失效;在push_back之后,capacity返回值与之前相比有改变,需要重新加在整个容器,此时first()和end()操作返回的迭代器都会失效;在删除erase和pop_back后,指向删除点和之后的迭代器全部失效;解决办法是获取erase返回的迭代器。std::list在删除erase的时候只有被删除的元素的迭代器失效,其他不受影响;解决办法也是获取erase返回的迭代器,或者是“ l.erase(it++);”,为啥it++就可以了:先把it值赋值给一个临时变量作为传递给erase的参数,然后参数处理要优先于函数调用,所以接下来执行it++ ,it已经指向了下一个地址,最后调用erase函数,释放掉第一步中保存的要删除的it的值的临时变量所指的位置。set和map同std::list。

  3. 所有容器都支持迭代器嘛?

    答:stack,queue、priority_queue不支持迭代器,vector和deque支持随机存取迭代器,list、set和map支持双向迭代器。

  4. std::map访问一个不存在的key会怎么样?

    答:如果不存在,map会插入一个元素,key为不存在的这个值,value为0,以std::map<int,int>为例子。

  5. std::stack、std::queue、std::priority_queue用什么创建?

    答:这种三种都是容器适配器,不支持迭代器,std::stack可以vector/deque/list创建一个先进后出的容器;queue使用deque或者list对象创建先进先出的容器,queue不能用vector 实现,因为没有pop_front 接口;std::priority_queue用vector/deque创建了一个排序队列,内部用二叉堆实现,不能用list 实现,因为list 只支持双向迭代器,而不支持随机迭代器。

  6. std::make_heap和std::sort_heap

    答:make_heap是将容器元素构造成二叉堆,std::less是大堆,std::greater是小堆(这俩是函数对象)

    template<typename T>
    bool campre(const T &a, const T &b)
    {
    	return a > b;
    }
    
    typedef  bool(*Func)(const int &, const int &);
    
    int main()
    {
    	/*MyIter<int> ite(new int(8));
    	cout << func(ite); */
    
    	/*std::priority_queue<int, std::vector<int>, std::less<int>>  q;
    
    	q.emplace(5);
    	q.emplace(6);
    	q.emplace(7);
    	q.emplace(8);
    	q.emplace(9);
    	q.emplace(10);
    
    	while (!q.empty())
    	{
    		cout << q.top() << " ";
    		q.pop();
    	}
    	cout << endl;
    	cout << q.size() << endl;*/
    
    	std::vector<int> v{ 3, 2, 4, 1, 5, 9 };
    	std::make_heap(v.begin(), v.end(),std::greater<int>());
    
    	for (auto &it : v)
    	{
    		cout << it << " ";
    	}
    	cout << endl;
    
    	Func a = campre<int>;
    
    	//必须已经是构建了堆,才能使用堆排序,大小堆类型匹配,支持第三个参数,可以是函数指针,也可以是函数对象
    	std::sort_heap(v.begin(), v.end(), a);
    	for (auto &it : v)
    	{
    		cout << it << " ";
    	}
    	cout << endl;
    	return 0;
    }
    //输出
    //1 2 4 3 5 9
    //9 5 4 3 2 1