GCC4.7.0库<array>,<vector>的简单讲解和C++11带来的变化

本文介绍了GCC4.7.0库中<vector>和<array>在C++11标准下的变化。文章详细讲解了vector的内存管理、allocator以及C++11引入的move构造函数、初始化列表、const迭代器接口、shrink_to_fit等功能。同时,对array的静态数组特性、支持tuple接口以及data()接口进行了阐述。
摘要由CSDN通过智能技术生成

    实习满2个月了.谨以此文缅怀本来应该是我最后一个暑假却用来实习的暑假.T_T(楼主强烈声明,实习生活很nice,前面只是吐槽,请无视)

    入正题,循惯例,上图先:

 

     简单来看,vector是继承_Vector_base,这里可以说分为两层去实现,在_Vector_base当中封装了跟内存分配相关的操作,如_M_allocate(),_M_deallocate()等,在_Vector_base当中有一个内置的结构,叫做_Vector_impl,他包含了3个指针,分别指向内存区域的起始,结束和当前使用到.这个就是vector的实现,所有的操作都是围绕在这3个指针来展开的,简单清晰._M_allocate(),_M_deallocate()其实就是对allocator申请(allocator())和释放(deallocator())接口的封装.

    看侯捷兄的源码剖析的时候,最开始讲的就是allocator,SGI的STL使用的allocator是用了内存池的技术,在分配的效率上可能会高一些.在GCC的库实现当中,默认使用的allocator是最最简单的new allocator,不使用带内存池的allocator原因可以在这里找到http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt04ch11.html ,GCC库当中其实提供了相当多的allocator,有机会再深入学习一下


 


 


 



    pointer的定义如下

      typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
        rebind<_Tp>::other _Tp_alloc_type;
      typedef typename __gnu_cxx::__alloc_traits<_Tp_alloc_type>::pointer
       	pointer;

    由于vector不是侵入式的容器,所以rebind<_Tp>其实是无关紧要,侵入式的容器主要是讲申请的内存结构跟T的关系,举例来说,vector<T>申请的内存就是T的数组,这个是没有变化的,但是对于像list<T>这样的容器,我们申请内存的时候除了主要类型T之外,我们还需要额外的两个指针,分别指向前导结点的后续结点,这样的行为可以想象成我们需要的内存被侵入,加了两个指针(总体就是T加上额外2个指针),但是我们传入模板参数的时候使用的是T,与2个额外的指针并没有什么关系.这里就需要rebind这个东西,把我们需要申请的类型重新进行绑定.加入额外的信息.__alloc_traits<>::pointer根据allocator萃取出相应的指针类型.

    与C++11相关的一些改动主要是:

    加入move构造函数,针对右值引用的构造优化,如

#ifdef __GXX_EXPERIMENTAL_CXX0X__
	_Vector_impl(_Tp_alloc_type&& __a)
	: _Tp_alloc_type(std::move(__a)),
	  _M_start(0), _M_finish(0), _M_end_of_storage(0)
	{ }
#endif
#ifdef __GXX_EXPERIMENTAL_CXX0X__
      _Vector_base(_Tp_alloc_type&& __a)
      : _M_impl(std::move(__a)) { }

      _Vector_base(_Vector_base&& __x)
      : _M_impl(std::move(__x._M_get_Tp_allocator()))
      { this->_M_impl._M_swap_data(__x._M_impl); }

      _Vector_base(_Vector_base&& __x, const allocator_type& __a)
      : _M_impl(__a)
      {
	if (__x.get_allocator() == __a)
	  this->_M_impl._M_swa
当你遇到无法打开源文件 `<thread>` 的问题时,这通常意味着你的编译器配置或者项目设置中存在一些问题。`<thread>` 是C++11标准中的一个头文件,它定义了线程支持,用于创建和管理线程。以下是一些可能的解决方法: 1. 确保你的编译器支持C++11或更高版本的C++标准。例如,如果你使用的是GCC或Clang,确保你使用的是4.8或更高版本。对于Visual Studio,确保你的项目配置为使用C++11或更新的标准。 2. 在你的源代码中,确保在包含 `<thread>` 头文件之前包含了 `<iostream>`,如下所示: ```cpp #include <iostream> #include <thread> ``` 3. 如果你已经在项目设置中启用了C++11(或更新的标准),并且仍然遇到问题,检查你的编译器设置中是否正确指定了标准。在GCC和Clang中,你可以通过添加 `-std=c++11`(或者更高版本的 `-std=c++14`、`-std=c++17` 等)到编译命令中。在Visual Studio中,可以在项目属性中设置C++语言标准。 4. 如果你是在使用某个IDE(集成开发环境),请检查项目设置中的包含目录或目录,确保它们包含了正确的标准路径。 5. 清理并重新构建你的项目,有时候这可以解决路径或依赖性问题。 6. 确认是否有拼写错误或者文件缺失的问题。如果`<thread>`文件确实不存在,可能是安装编译器或开发环境时出现了问题。 如果以上方法都不能解决你的问题,可能需要具体分析你的编译器设置和项目配置,或者查看编译器提供的错误信息以获得更准确的解决方案。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值