(Boolan) C++ STL与泛型编程——容器1

本文探讨了C++ STL中的泛型编程思想,对比了面向对象编程与泛型编程的区别。文章深入分析了STL容器,如list、vector和array,以及迭代器的设计原则,并提到了分配器在容器内存管理中的作用。此外,还讨论了不同版本GCC中容器实现的差异,如2.9版的alloc分配器设计。
摘要由CSDN通过智能技术生成

STL标准库是开发中的利器,也是开发的宝库。

这次的源码分析主要以GNU C++的2.9和4.9版本为例,因为4.9之后代码重构,核心部分发生了巨大的变化,再次分别分析一下。

以GCC为例的标准库位置: ....\x.x.x\include\c++\


本地的目录

对于2.9和4.9最大的差别其实就是,2.9主要采用了泛型编程的思想,4.9引入了大量的面向对象编程的思想。

OOP(Object-Oriented Programming 面向对象编程) vs. GP(Generic Programming 泛型编程)

  • OOP
    • OOP主要的思想是将datas和methods关联在一起的思想。
      也就是数据放在类中,操作数据的方法也是放在类中。(就像我以前举的一个例子,如果class 猫身上有毛,那么他必须有一个方法来管理他的毛,也就是舔毛()这个函数。只需要猫咪.舔毛();来调用这个函数,就可以管理和操作对应的数据)
  • GP
    • GP的主要思想是将datas和methods分开
      在STL中大量使用到了GP的思想,来实现了数据和算法的分离,那么,算法如何才能操作数据呢,这中间的桥梁就是Iterators(迭代器)了,通过Iterator,算法可以从容器中获取到需要的数据,同样也就可以起到操作数据的目的。
      为何STL会采用GP的思想呢?其实使用了GP思想,类和类之间的关系不会那么紧密,也就不会产生很强的耦合性,便于不同的成员,协同开发不同的模块,有助于加快项目开发得效率,大家只需要依据“中间商”Iterator来编写各自代码就行了。

对于OOP来说最好的一点就是,方法和数据在同一个类中,那么方法是专门为类所设计的。比较方便能够管理其中的数据。GP由于数据和方法分离,操作的时候,难免有些数据,不能被这个方法所操作。比如,list 不能使用::sort() 进行排序,那到底是为什么呢?

  • 看看::sort()的源码,发现问题所在
template <class RandomAccessIterator>
inline void sort(RandomAccessIterator first, RandomAccessIterator last)
{
    if(first != last)
    {
        _introsort_loop(first, last, value_type(first), __lg(last-first)*2);
        __final_insertion_sort(first, last);
    }
}
.....
template <class RandomAccessIterator, class T, class Size>
void __introsort_loop(RandomAccessterator first, RandomAccessIterator last, T*, Size depth_limit)
{
    ......
    RandomAccessIterator cut = __unguarded_partition(first, last, T(__median(*first, *(first + (last - first)/2), *(last - 1))));
//由于此处牵扯到了Iterator的下标运算
//list不是一个连续空间,前后节点之间靠指针相连,所以list 的Iterator不具备下表直接运算的能力,所以,list不能直接使用::sort()来进行排序
//也正是由于这个原因::sort() 只能为RandomAccessIterator来进行排序
    ......
}
  • 那既然如此,在STL中,难道数据不适合就不能使用了,是否有其他方式来使用呢?
    • 以max()为例
//标准库中的两个函数
template<class T>
inline const T& max(const T& a, const T& b){
    return a < b ? b: a;
}

template<class T, class Compare>
inline const T& max(const T& a, const T& b, Compare comp){
    return comp(a, b)? b: a;
}
//如何使用
//定义一个依据长度比较大小的函数
bool strLonger(const T& a, const T& b){
    return a.size() < s2.size();
}
cout << "max of zoo and hello:" 
  << max(string("zoo"), string("hello")) << endl;

cout << "longer of zoo and hello: " 
   << max(string("zoo"), string("hello"), strLonger) << endl;

分配器

分配器是容器管理内存的工具,对于容器的效率起着比较重要的作用
在正式开始说allocator之前,先说几句operator new()和 malloc()以及operator delete() 和free()
在创建对象时,会调用operator new(),而operator new()中分配内存实际也还是调用有C语言的Runtime Library所提供的malloc(),再由系统来分配所需要的内存;销毁对象时,则会使用operator delete(),而他实际会调用free()。

  • vc中的operator new()
void *operator new (size_
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值