- (1)set 容器完美对应于数学意义上的集合的概念,最大的要求即是不允许元素重复;
- (2)关联式容器有别于序列式容器的地方的全部原因皆在于,其底层的实现是红黑树,首先是一棵树,一棵平衡二叉搜索树。
关联式容器,应该使用其所提供的 find 成员来搜寻元素
由于 RB-tree(红黑树)是一种平衡二叉搜索树,具有较好的自动排序的效果。关联式容器(set/multiset、map/multimap)都需根据元素的键值(key)对所有元素自动排序,所以标准的 STL set/map 都是以红黑树为底层机制 。set 的源码如下:
template<class Key,
class Compare = less<Key>,
class Alloc = alloc>
class set
{
public:
//typedefs
typedef Key key_type;
typedef Key value_type;
typedef Compare key_compare;
typedef Compare value_compare;
typedef rb_tree<key_type, value_type,
identity<value_type>, key_compare, Alloc> rep_type;
rep_type t;
// 采用红黑树(RB-tree)来表现 set
public:
typedef typename rep_type::const_iterator const_iterator;
typedef typename rep_type::const_iterator iterator;
// 将 set 的iterator定义为RB-tree的 const_iterator,
// 这表示 set 的迭代器无法执行写入操作。
};
我们来看其内部对 find 成员函数的实现:
iterator find(const key_type& x) const
{ return t.find(x); }
面对关联式容器,应使用其所提供的 find 成员函数来搜寻元素(其实现是调用底层的红黑树的 find 成员,如上所示),会比使用 STL 算法 find() 更有效率,因为 STL 算法 find 只是循序搜寻(未利用 set 的自动排序特性)。
私有成员变量 vs 容器
数据是精髓和灵魂。
私有成员变量之于一个类,正如容器之于 STL;
私有成员变量之于一个类
一般而言,类是对私有成员变量的封装与抽象,类内的私有成员函数为公用成员函数服务,公有成员函数围绕私有成员变量展开(如果不操作私有成员变量),是没必要把公有成员函数放在类内实现的。
容器之于 STL
侯捷老师将STL,划分为六大组件,
- 容器(containers):自不待言,用来存放数据,是一种 class template
- 算法(Algorithms):独立于容器的设计,最终用来操作数据,是一种 function template
- 迭代器(Iterators):扮演容器与算法之间的胶合剂,是所谓的“泛型指针”
- 仿函数(functors):行为类似函数,作为算法的参数,搭配算法使用
- 配接器(Adapters):可用来修饰容器、仿函数、迭代器
- 配置器(Allocators):负责空间配置与管理
关联式容器的 erase() 成员
在 C++ 11 之前,关联式容器的 erase() 函数不返回任何内容(返回类型为 void),这是为了效率。在一个关联式容器内查找元素并返回其后继者,可能会花不少时间,因为容器被实现为一棵 binary tree。