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
`std::allocator<void>` 是 C++ 标准中的一个模板类,用于管理动态内存分配。它通常与容器如 `std::vector`, `std::list`, 和 `std::unordered_map` 结合使用,以在这些容器内部存储元素。然而,在给定的代码片段[^1]中,并未直接提及 `std::allocator<void>`。 `std::unordered_map` 的键和值都是自定义的,其中键(`std::vector<int>`)和值(`std::pair<std::vector<double>, std::vector<int>>`)都使用了 `std::vector`。这里的 `std::unordered_map` 的实现并没有明确使用 `std::allocator<void>`,因为它不需要一个通用的内存分配器来存储整个映射结构。 在提到的错误信息[^2]中,关于 `std::__cxx11::basic_string` 的赋值操作,实际上是在讨论字符串类型,而不是 `void` 类型。这个错误是由于运行时使用的 GCC 版本和编译时使用的 GCC 版本不匹配造成的,与 `std::allocator<void>` 没有直接关系。 如果你想了解 `std::allocator<void>` 的具体用法,你可以创建一个简单的示例: ```cpp #include <memory> #include <vector> // 创建一个空的 void 分配器实例 template <> std::allocator<void> my_allocator(); int main() { // 使用 void 分配器创建一个 vector std::vector<void*, my_allocator<void>> vec; // 注意,不能直接存储 void*,这通常是空指针,用于表示未初始化的位置 vec.push_back(nullptr); // 错误:无法对 void* 执行操作,因为它们没有类型 return 0; } // 定义 void 分配器模板实例 template <> struct std::allocator<void> : public std::allocator<char> {}; // 实现构造函数和其他必要的成员函数 ``` 尽管如此,实际场景中很少见到直接使用 `std::allocator<void>` 存储对象,因为它是用来处理不确定类型的内存分配,但通常会更倾向于明确指定要存储的对象类型。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值