操作符重载
https://en.cppreference.com/w/cpp/language/operators
不能重载的操作符 operators :: (scope resolution), . (member access), .* (member access through pointer to member), and ?: (ternary conditional) cannot be overloaded.
链表的迭代器:重定义了所有指针的操作1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69template<typename _Tp>
struct _List_iterator
{
typedef _List_iterator<_Tp> _Self;
typedef _List_node<_Tp> _Node;
typedef ptrdiff_t difference_type;
typedef std::bidirectional_iterator_tag iterator_category;
typedef _Tp value_type;
typedef _Tp* pointer;
typedef _Tp& reference;
_List_iterator()
: _M_node() { }
explicit
_List_iterator(__detail::_List_node_base* __x)
: _M_node(__x) { }
// Must downcast from _List_node_base to _List_node to get to _M_data.
reference
operator*() const
{ return static_cast<_Node*>(_M_node)->_M_data; }
pointer
operator->() const
{ return std::__addressof(static_cast<_Node*>(_M_node)->_M_data); }
_Self&
operator++()
{
_M_node = _M_node->_M_next;
return *this;
}
_Self
operator++(int)
{
_Self __tmp = *this;
_M_node = _M_node->_M_next;
return __tmp;
}
_Self&
operator--()
{
_M_node = _M_node->_M_prev;
return *this;
}
_Self
operator--(int)
{
_Self __tmp = *this;
_M_node = _M_node->_M_prev;
return __tmp;
}
bool
operator==(const _Self& __x) const
{ return _M_node == __x._M_node; }
bool
operator!=(const _Self& __x) const
{ return _M_node != __x._M_node; }
// The only member points to the %list element.
__detail::_List_node_base* _M_node;
};
源码位置 generic programming
\devcpp\MinGW64\lib\gcc\x86_64-w64-mingw32\4.8.1\include\c++\bits
数据list/deque/vector和方法algorithm分开
全局函数::sort(c.begin(),c.end());
通过iterator/泛化指针作为接口
stl_algobase:1
2
3
4
5
6
7
8
9
10
11template<typename _Tp>
inline const _Tp&
min(const _Tp& __a, const _Tp& __b)
{
// concept requirements
__glibcxx_function_requires(_LessThanComparableConcept<_Tp>)
//return __b < __a ? __b : __a;
if (__b < __a)
return __b;
return __a;
}
1 | template<typename _Tp, typename _Compare> |
list不用全局sort 因为全局sort要求传入的指针是randomaccess
stl_algobase:1
2
3
4
5
6
7
8
9
10
11template<typename _RandomAccessIterator>
inline void
sort(_RandomAccessIterator __first, _RandomAccessIterator __last){
...
if (__first != __last)
{
std::__introsort_loop(__first, __last,
std::__lg(__last - __first) * 2);
std::__final_insertion_sort(__first, __last);
}
}
模板
1.类模板
在class前加template<typename T>
2.函数模板 写typename和class功能相同1
2
3
4
5template<class T>
inline
const T& min(const T& a,const T& b){
return b<a?b:a;
}
3.成员模板
operator new()/malloc()
operator new 调用malloc
newop.cpp1
2
3
4
5
6
7
8
9
10
11oid *__CRTDECL operator new(size_t count) _THROW1(_STD bad_alloc)
{ // try to allocate size bytes
void *p;
while ((p = malloc(count)) == 0)
if (_callnewh(count) == 0)
{ // report no memory
static const std::bad_alloc nomem;
_RAISE(nomem);
}
return (p);
}
STL
分配器Allocator支持容器,处理容器的内存。
容器Containers数据和算法Algorithms操作分开。不是OO设计,是模板编程。
迭代器是泛化指针 是容器和算法的桥梁。
仿函数Functors
容器
1 Sequence Containers:
Array\vector\deque\list循环双端链表\forwardlist单向链表
2 Associative Container:Set\Multiset,Map\Multimap
3 unordered Containers:
HashTable:Separate Chaning。
array
不能改变大小
milli-seconds : 11
array.size()= 500000
array.front()= 41
array.back()= 29794
数组起点的内存位置
array.data()= 0x49c040
1 |
|
vector
milli-seconds : 6326
vector.max_size()= 2305843009213693951
vector.size()= 1000000
vector.front()= 41
vector.back()= 12679
vector.data()= 0x33c5040
vector.capacity()= 1048576
target (0~32767): 654
target:654
std::find(), milli-seconds : 1
found, 654
bsearch(), milli-seconds : 1387
found, 654
1 |
|
List
milli-seconds : 5165
list.size()= 1000000
list.max_size()= 768614336404564650
list.front()= 41
list.back()= 12679
target (0~32767): 554
//find循序查找用时
std::find(), milli-seconds : 2
found, 554
//容器内的sort用时
c.sort(), milli-seconds : 2098
1 |
|
单向链表
没有push_back(太慢)只有push_front
只能得到第一个元素不能得到最后
milli-seconds : 5716
forward_list.max_size()= 1152921504606846975
forward_list.front()= 12679
target (0~32767): 3443
std::find(), milli-seconds : 2
found, 3443
c.sort(), milli-seconds : 2155
1 |
|
deque
gnuC的,不是c++11的,用法与forward_list相同
slist:
milli-seconds : 5096
slist.max_size()= 18446744073709551615
slist.front()= 12679
target (0~32767): 33
std::find(), milli-seconds : 4
found, 33
c.sort(), milli-seconds : 12281
2
__gnu_cxx::slist<string> c;
deque
分段连续
milli-seconds : 6119
deque.size()= 1000000
deque.front()= 41
deque.back()= 12679
deque.max_size()= 2305843009213693951
target (0~32767): 354
std::find(), milli-seconds : 3
found, 354
sort(), milli-seconds : 1551
1 |
|
容器适配器stack/queue用deque实现 push,pop
没有iterator,没有find,不然就可以改变中间的值
stack:
milli-seconds : 5545
stack.size()= 1000000
stack.top()= 12679
stack.size()= 999999
stack.top()= 171721
stack<string> c;
queue:
milli-seconds : 4943
queue.size()= 1000000
queue.front()= 41
queue.back()= 12679
queue.size()= 999999
queue.front()= 18467
queue.back()= 126791
2
3queue<string> c;
c.front();
c.back();
multiset 可以当成关联数据库
放进去的时候就排序了,红黑树
标准库的find和容器的find
milli-seconds : 7833
multiset.size()= 1000000
multiset.max_size()= 461168601842738790
target (0~32767): 23489
std::find(), milli-seconds : 124
found, 23489
c.find(), milli-seconds : 0
found, 23489
1 |
|
multimap c.insert(pair<long,string>(i,buf));
milli-seconds : 6038
multimap.size()= 1000000
multimap.max_size()= 384307168202282325
target (0~32767): 293283
c.find(), milli-seconds : 0
found, value=8239
1 |
|
unordered_multiset(hashtable)不是红黑树是hash表
milli-seconds : 5832
unordered_multiset.size()= 1000000
unordered_multiset.max_size()= 768614336404564650
unordered_multiset.bucket_count()= 1056323
unordered_multiset.load_factor()= 0.94668
unordered_multiset.max_load_factor()= 1
unordered_multiset.max_bucket_count()= 768614336404564650
bucket #33 has 36 elements.
bucket #37 has 41 elements.
bucket #79 has 16 elements.
target (0~32767): 555
std::find(), milli-seconds : 81
found, 555
c.find(), milli-seconds : 0
found, 555
1 |
|
unordered_multimap
milli-seconds : 6266
unordered_multimap.size()= 1000000
unordered_multimap.max_size()= 768614336404564650
target (0~32767): 42342
c.find(), milli-seconds : 0
found, value=9100
1 |
|
set 红黑树
放了1000000但是只有32768大小,0~32767
milli-seconds : 6963
set.size()= 32768
set.max_size()= 461168601842738790
target (0~32767): 3
std::find(), milli-seconds : 4
found, 3
c.find(), milli-seconds : 0
found, 3
1 |
|
map 可以用[]自动变成一个pair c[i] = string(buf);
milli-seconds : 6843
map.size()= 1000000
map.max_size()= 384307168202282325
target (0~32767): 4
c.find(), milli-seconds : 0
found, value=19169
1 |
|
unordered_set/map
1 | unordered_set<string> c; |
GNU C以前用hash_set
,hash_map
,hash_multiset
,hash_multimap
#include <ext\hash_set>
1
2
__gnu_cxx::hash_multimap<long, string> c;
GNUC的分配器 VC里名字不一样
(1) std::allocator
how many elements: 1000000
a lot of push_back(), milli-seconds : 4975
(2) malloc_allocator
how many elements: 1000000
a lot of push_back(), milli-seconds : 4768
(3) new_allocator
how many elements: 1000000
a lot of push_back(), milli-seconds : 4790
(4) __pool_alloc
内存池
how many elements: 1000000
a lot of push_back(), milli-seconds : 7357
(5) __mt_alloc
多线程
how many elements: 1000000
a lot of push_back(), milli-seconds : 4881
(6) bitmap_allocator
how many elements: 1000000
a lot of push_back(), milli-seconds : 7420
1 |
|
可以直接使用allocate 但是不要用 小分配用malloc 大分配用容器
1 | __gnu_cxx::bitmap_allocator<int> alloc6; |