C++学习之路: STL探索 list<>的一些基本操作(成员函数)
1.当我们把类体内的一些成员函数设置为private时, 外部用户(除了该类内部的用户)则无法调用该函数。
1 #include <iostream> 2 #include <string> 3 #include <vector> 4 using namespace std; 5 6 //Test不支持复制和赋值。所以不能放入vector 7 class Test 8 { 9 public: 10 Test() {} 11 12 private: 13 //设为私有,禁用了Test的复制和赋值能力 14 Test(const Test &); //用于复制 15 void operator=(const Test &); //用于赋值 16 }; 17 18 int main(int argc, const char *argv[]) 19 { 20 vector<Test> vec; 21 Test t; 22 vec.push_back(t); 23 return 0; 24 }
我们稍微解释一下上面那个 operator操作符, 那个是类的赋值操作函数, 例如我们定义 Test t1, t2 它们的+法,* 法默认的定义由编译器载入, 当我们把赋值 操作设为私有, main函数中的赋值
则无法进行, 因为赋值要调用operator ,但是它已经是私有的了, 外部用户无法访问。 但是类的内部成员还是可以调用operator。
2.list的一些基本操作
除了push_back 多了一个push_front, 还有一个insert, 有一个find()用于查找成员的POS,这些成员函数都要多个版本, 即它们的输入参数是多样化的。
迭代器是重要的,参数,一定要好好学习迭代器。
1 #include <iostream> 2 #include <string> 3 #include <vector> 4 #include <list> 5 #include <map> 6 #include <set> 7 #include <algorithm> 8 using namespace std; 9 10 11 void print(const list<string> &lst) 12 { 13 for(const string &s : lst) 14 { 15 cout << s << " "; 16 } 17 cout << endl; 18 } 19 20 int main(int argc, const char *argv[]) 21 { 22 list<string> lst; 23 lst.push_back("hangzhou"); 24 lst.push_front("tianjin"); 25 lst.push_front("shanghai"); 26 27 print(lst); 28 29 lst.insert(lst.begin(), "shenzhen"); 30 print(lst); 31 32 lst.insert(lst.end(), "longhua"); 33 print(lst); 34 35 36 list<string>::iterator it = find(lst.begin(), lst.end(), "tianjin"); 37 lst.insert(it, "fenghua"); 38 print(lst); 39 40 41 return 0; 42 }
3.删除操作
1 #include <iostream> 2 #include <string> 3 #include <vector> 4 #include <list> 5 #include <algorithm> 6 using namespace std; 7 8 9 10 void print(const list<string> &lst) 11 { 12 for(const string &s : lst) 13 { 14 cout << s << " "; 15 } 16 cout << endl; 17 } 18 /* 19 * 删除单个元素 20 * 21 */ 22 int main(int argc, const char *argv[]) 23 { 24 list<string> lst; 25 lst.push_back("hangzhou"); 26 lst.push_front("tianjin"); 27 lst.push_front("shanghai"); 28 29 30 print(lst); 31 list<string>::iterator it = find(lst.begin(), lst.end(), "tianjin"); 32 lst.insert(it, 3, "beijing"); 33 print(lst); 34 35 36 it = find(lst.begin(), lst.end(), "tianjin"); 37 lst.erase(it); 38 print(lst); 39 40 41 return 0; 42 }
(2).注意迭代器失效的问题,因为list是非线性存储,是离散的,当我们删除一个成员时, 迭代器 it会变成野指针,无指向,对它++操作是没有意义的。、
必须接收erase的返回值, erase会返回下一元素的迭代器。这样就不需要++操作的。 vector是线性的,所以可以不用接收返回的迭代器。
#include <iostream> #include <string> #include <vector> using namespace std; void print(const vector<int> &lst) { for(int t : lst) { cout << t << " "; } cout << endl; } int main(int argc, const char *argv[]) { vector<int> vec; srand(23456); for(int i = 0; i != 20; ++i) { vec.push_back(rand() % 100); } print(vec); vector<int>::iterator it = vec.begin(); while(it != vec.end()) { if(*it % 2 == 0) //vec.erase(it); it = vec.erase(it); // else ++it; } print(vec); return 0; }
(3).如果是list,it 如果不接收返回的迭代器,就无所指向,将出现段错误。
1 #include <iostream> 2 #include <string> 3 #include <vector> 4 #include <list> 5 #include <algorithm> 6 using namespace std; 7 8 void print(const list<int> &lst) 9 { 10 for(int t : lst) 11 { 12 cout << t << " "; 13 } 14 cout << endl; 15 } 16 17 int main(int argc, const char *argv[]) 18 { 19 list<int> lst; 20 srand(23456); 21 22 for(int i = 0; i != 20; ++i) 23 { 24 lst.push_back(rand() % 100); 25 } 26 print(lst); 27 28 list<int>::iterator it = lst.begin(); 29 while(it != lst.end()) 30 { 31 if(*it % 2 == 0) 32 //lst.erase(it); //error 段错误, 删除操作后, 迭代器无指向, ++操作指向非法内存,非法访问导至段错误。 33 it = lst.erase(it); 34 else 35 ++it; 36 } 37 38 39 print(lst); 40 41 42 43 return 0; 44 }
4.输入迭代器范围还可以删除一段元素
1 #include <iostream> 2 #include <string> 3 #include <vector> 4 #include <algorithm> 5 using namespace std; 6 7 int main(int argc, const char *argv[]) 8 { 9 vector<string> vec; 10 vec.push_back("beijing"); 11 vec.push_back("shanghai"); 12 vec.push_back("tianjin"); 13 vec.push_back("shenzhen"); 14 vec.push_back("changchun"); 15 16 for(vector<string>::iterator it = vec.begin(); it != vec.end(); ++it){ 17 cout << *it << " "; 18 } 19 cout << endl; 20 21 vector<string>::iterator it1, it2; 22 it1 = find(vec.begin(), vec.end(), "shanghai"); 23 24 it2 = find(vec.begin(), vec.end(), "shenzhen"); 25 26 vec.erase(it1, it2); //删除一段元素。 27 28 29 for(vector<string>::iterator it = vec.begin(); it != vec.end(); ++it){ 30 cout << *it << " "; 31 } 32 cout << endl; 33 34 35 36 37 return 0; 38 }