c++ 11
1.forward_list单向链表
成员函数
构造函数
- 构造函数 forward_list (公有成员函数 )
析构函数
- 析构函数 forward_list (公有成员函数 )
=操作运算符
- 分配内容 (公有成员函数)
迭代器
- before_begin
- 返回指向开始之前的迭代器指针 (公有成员函数 )
- begin
- 返回指向开始的迭代器指针 (公有成员类型 )
- end
- 返回指向结束的迭代器指针 (公有成员函数 )
- cbefore_begin
- 返回指向开始之前的常迭代器指针 (公有成员函数 )
- cbegin
- 返回指向指向开始的常迭代器指针 (公有成员函数 )
- cend
- 返回指向结束的常迭代器指针 (公有成员函数 )
容量
- empty
- 判断是否为空 (公有成员函数 )
- max_size
- 返回容量的最大值 (公有成员函数 )
元素的获取
- front
- 获得第一个元素值 (公有成员函数 )
修饰符
- assign
- 分配内容 (公有成员函数 )
- emplace_front
- 构造并插入元素到首位置 (公有成员函数 )
- push_front
- 插入元素到首位置 (公有成员函数 )
- pop_front
- 删除首位置的元素 (公有成员函数 )
- emplace_after
- 构造并插入元素 (公有成员函数 )
- insert_after
- 插入元素 (公有成员函数 )
- erase_after
- 擦除元素 (公有成员函数 )
- swap
- 交换内容 (公有成员函数 )
- resize
- 改变容量大小 (公有成员函数 )
- clear
- 清除内容 (公有成员函数 )
操作
- splice_after
- 移动元素从另一个前向链表 (公有成员函数 )
- remove
- 删除特定值的元素 (公有成员函数 )
- remove_if
- 删除符合条件的元素 (公有成员模板函数 )
- unique
- 删除重复值 (成员函数 )
- merge
- 合并排序链表 (公有成员函数 )
- sort
- 容器中的元素排序 (公有成员函数 )
- reverse
- 反转元素的顺序 (公有成员函数 )
观察者
- get_allocator
- 获取分配器 (公有成员函数 )
全局函数
- operators (forward_list)
- 链表的全局关系运算函数 (函数模板 )
- swap (forward_list)
- 交换两个前向链表的内容(函数模板 )
- 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
- 2.erase函数的原型如下:
-
(1)string& erase ( size_t pos = 0, size_t n = npos );
(2)iterator erase ( iterator position );
(3)iterator erase ( iterator first, iterator last );
也就是说有三种用法:
(1)erase(pos,n); 删除从pos开始的n个字符,比如erase(0,1)就是删除第一个字符
(2)erase(position);删除position处的一个字符(position是个string类型的迭代器)
(3)erase(first,last);删除从first到last之间的字符(first和last都是迭代器)函数remove_if()移除序列[start, end)中所有应用于谓词p返回true的元素.
此函数返回一个指向被修剪的序列的最后一个元素迭代器.
记住, remove_if()并不会实际移除序列[start, end)中的元素; 如果在一个容器上应用remove_if(), 容器的长度并不会改变(remove_if()不可能仅通过迭代器改变容器的属性), 所有的元素都还在容器里面. 实际做法是, remove_if()将所有应该移除的元素都移动到了容器尾部并返回一个分界的迭代器. 移除的所有元素仍然可以通过返回的迭代器访问到. 为了实际移除元素, 你必须对容器自行调用erase()以擦除需要移除的元素. 这也是erase-remove idiom名称的由来:
container.erase(remove_if(container.begin(), container.end(), pred), container.end());
remove_if()类似于partition(), 但有两点不同: 1) 它们使用的谓词条件刚好相反. 2) remove_if只强调前面部分(第二部分不再需要了).
remove_if()以线性时间(linear time)运行.
remove_if()不能用于关联容器如set<>或map<>.
3.swap
新标准中提供了非成员版本的swap操作,此操作对array容器,会交换元素的值;对其他容器,则只交换容器的内部结构,并不进行元素值的拷贝操作,所以在这种情况下是非常迅速的。
正因如此,当swap array后,原来array上的迭代器还依然指向原有元素,只是元素的值变了;
而swap非array容器之后,原来容器上的迭代器将指向对方容器上的元素,而指向的元素的值却保持不变。对于vector,指针交换了,但是容器内容并没有改变,尽管遍历的时候 it6_2 = c6.begin(),但是it6_2实际上已经是指向7的指针了
1 #include <vector> 2 #include <iostream> 3 #include <algorithm> 4 #include <functional> 5 #include<forward_list> 6 using namespace std; 7 int main() 8 { 9 vector<int> c6 = {0, 1, 2, 3, 4}; 10 vector<int> c7 = {5, 6, 7, 8, 9}; 11 auto it6_1 = c6.begin(); 12 auto it7_1 = c7.begin(); 13 swap(c6, c7); 14 for(auto it6_2 = c6.begin(); it6_2 != c6.end(); it6_2++) 15 cout<<*it6_2<<'\t'; 16 cout<<endl; 17 18 for(auto it7_2 = c7.begin(); it7_2 != c7.end(); it7_2++) 19 cout<<*it7_2<<'\t'; 20 cout<<endl; 21 22 cout<<(it6_1 == c7.begin())<<'\t'<<(it7_1 == c6.begin())<<endl; 23 24 array<int, 5> c8 = {0, 1, 2, 3, 4}; 25 array<int, 5> c9 = {5, 6, 7, 8, 9}; 26 auto it8_1 = c8.begin(); 27 auto it9_1 = c9.begin(); 28 swap(c8, c9); 29 cout<<(it8_1 == c8.begin())<<'\t'<<(it9_1 == c9.begin())<<endl; 30 }
4。emplace
class TestData
{
public:
TestData(string name, int age, double salary): name(name), age(age), salary(salary)
{}
private:
string name;
int age;
double salary;
};vector<TestData> c10;
c10.emplace_back("yubo", 26, 100000000000.0);
//c10.push_back("laowang", 56, 10.5); // wrong. no 3 params push_back
c10.push_back(TestData("laowang", 56, 10.5));
cout<<c10.size()<<endl;
}不用传对象了
shrink_to_fit
一般可变长容器会预先多分配一部分内存出来,以备在后续增加元素时,不用每次都申请内存。所以有size和capacity之分。size是当前容器中存有元素的个数,而capacity则是在不重新申请内存的情况下,当前可存放元素的最大数目。而shrink_to_fit就表示将capacity中的多余部分退回,使其回到size大小。但是,这个函数的具体效果要依赖于编译器的实现……
无序关联容器:#include <map>
#include <iostream>
#include <algorithm>
#include <functional>
#include<forward_list>
#include<unordered_map>using namespace std;
int main()
{
unordered_map<string, int> c12;
map<string, int> c13;
string string_keys[5] = {"aaa", "bbb", "ccc", "ddd", "eee"};
for(int i = 0; i < 5; i++)
{
c12[string_keys[i]] = i;
c13[string_keys[i]] = i;
}
for(auto it13 = c13.begin(); it13 != c13.end(); it13++)
cout<<it13->first<<':'<<it13->second<<'\t';
cout<<endl;
cout<<"unordered map:\n";
for(auto it12 = c12.begin(); it12 != c12.end(); it12++)
cout<<it12->first<<':'<<it12->second<<'\t';
cout<<endl;
}shared_ptr智能指针
shares_ptr<string> ptr=make_shared<string>("dfsdf");
shared_ptr可以使用一个new表达式返回的指针进行初始化,但是不能用返回的指针赋值 ;shared_ptr可以通过reset方法重置指向另一个对象,此时原对象的引用计数减一。
shared_ptr采用引用计数的方式管理所指向的对象。当有一个新的shared_ptr指向同一个对象时(复制shared_ptr等),引用计数加1。当shared_ptr离开作用域时,引用计数减1。当引用计数为0时,释放所管理的内存。
这样做的好处在于解放了程序员手动释放内存的压力。之前,为了处理程序中的异常情况,往往需要将指针手动封装到类中,通过析构函数来释放动态分配的内存;现在这一过程就可以交给shared_ptr去做了。
using namespace std;
int main()
{
cout<<"test shared_ptr base usage:"<<endl;
shared_ptr<string> p1 = make_shared<string>("");
if(p1 && p1->empty())
*p1 = "hello";auto p2 = make_shared<string>("world");
cout<<*p1<<' '<<*p2<<endl;cout<<"test shared_ptr use_count:"<<endl;
cout<<"p1 cnt:"<<p1.use_count()<<"\tp2 cnt:"<<p2.use_count()<<endl;auto p3 = p2;
拷贝构造:
cout<<"p1 cnt:"<<p1.use_count()<<"\tp2 cnt:"<<p2.use_count()<<"\tp3 cnt:"<<p3.use_count()<<endl;
p2 = p1;
cout<<"p1 cnt:"<<p1.use_count()<<"\tp2 cnt:"<<p2.use_count()<<"\tp3 cnt:"<<p3.use_count()<<endl;
}class TestClass
{
public:
TestClass() = default;
TestClass(const int i, const char c): member_i(i), member_c(c) {}
TestClass(const int i): TestClass(i, 0) { member_c = 'T';}(委托构造)
TestClass(const TestClass&) = default;
TestClass operator=(const TestClass&);int member_i;
char member_c;
};
int main()
{TestClass tc2(2);
cout<<"test =default class copy construct:\n";
TestClass tc3(tc2);
TestClass tc4 = tc2;
cout<<tc3.member_i<<'\t'<<tc3.member_c<<endl;
cout<<tc4.member_i<<'\t'<<tc4.member_c<<endl;
}