一、异常处理
0. 一般用法1 class MyException { // 自定义异常 public : MyException(){errorCode = -1;} MyException(int code) {errorCode = code;} int get(){return errorCode;} private : int errorCode; }; void fun () { try { throw MyException(1); } catch (MyException& e) { // 一般都是使用引用,避免对象拷贝 cout << "exception: " << e.get() << endl; } } int main() { fun(); return 0; } 一般用法2: class MyException1 {}; class MyException2 {}; void fun () { try { int flag = 3; // 试着改变flag的值,以走遍每个分支 if (flag == 1) { throw MyException1(); } else if (flag == 2) { throw MyException2(); } else { throw string(); } } catch (MyException1& e) { cout << "exception1 handled." << endl; } catch (MyException2& e) { cout << "exception2 handled." << endl; } catch (...) { // catch-all cout << "other exception handled." << endl; } cout << "after exception handled." << endl; } int main() { fun(); return 0; } 1. 声明和定义的throw列表要完全一致 // 函数声明和函数定义,两者的throw列表必须完全一致 void sample() throw(string); // JAVA里面是:void sampe() throws StringException; //void sample(){} // error. 没有throw列表 //void sample() throw (int) {} // error. throw列表不一样 //void sample() throw (string, int){} // error. throw列表不一致 void sample() throw (string) {} // ok. throw列表完全一致 2. c++里面可以throw任何类型的异常(包括内置类型如int,标准库类型如string,自定义类型如MyException) 3. throw列表1 -- 函数内部抛出的异常和throw列表一致 // throw列表表示函数只抛出列表里面的异常类型 void sample() throw (string) { // 保证只抛出string类型 throw string("xxxx"); // OK.抛出了列表中指定的异常 } int main() { try { sample(); } catch (string& str) { // 异常被捕捉到 cout << "exception: " << str << endl; } return 0; } 4. throw列表2 -- 函数内部抛出的异常和throw列表不一致 void sample() throw (string) { // 保证只抛出string类型 throw int(-1); // 但是却抛出了非string的异常。 // 此时c++会调用库函数unexpected(),里面会调用库函数terminate()退出 } int main() { try { sample(); // 抛出了int类型的异常 } catch (string& str) { cout << "exception: " << str << endl; } catch (...) { // 即便有catch-all,这里仍不会被执行。因为c++自动调用了unexpected()退出 cout << "catch all exceptioin" << endl; } cout << "after exception handler." << endl; return 0; } 5. throw列表3 -- 函数指针的throw列表 // 函数指针中的throw列表会被忽略,而采用和其指向的函数一样的throw列表 void sample() throw (string) { } void (*pf)() throw (string) = sample; // ok。一致。 void (*pf2)() throw (string,int) = sample; // ok.更严格 void (*pf3)() throw() = sample; // ok。 void (*pf4)() = sample; // ok. void (*pf5)() throw (int) = sample; // ok. 6.
二、泛型算法
void printVec(vector<string>& svec); bool comparestr(const string& str1, const string& str2); // 函数对象 class LessThan { public: // 最关键的是对()的重载 bool operator()(const string& str1, const string& str2) { return str1.size() < str2.size(); } }; class GreaterThan{ public: GreaterThan(){_size = 3;} GreaterThan(int size) {_size = size;} int size(){return _size;} bool operator() (const string &str) {return str.size()>_size;} private : int _size; }; class PrintElem { public : void operator() (const string& elem) { cout << elem << " "; } }; void fun () { string arr[] = {"aaa", "bbb", "ccc", "ddd"}; vector<string> svec(arr, arr+4); printVec(svec); vector<string> svec2; svec2.push_back("xxx"); // xxx // copy copy(svec.begin(), svec.end(), back_inserter(svec2)); printVec(svec2); // xxx,aaa,bbb,ccc,ddd // sort sort(svec2.begin(), svec2.end()); printVec(svec2); // aaa,bbb,ccc,ddd,xxx svec2.push_back("xxx"); svec2.push_back("aaa"); printVec(svec2); // aaa,bbb,ccc,ddd,xxx,xxx,aaa // unique 只删除相邻的相同元素,把那些独立的元素从左到右依次排列 vector<string>::iterator removedIter = unique(svec2.begin(), svec2.end(), comparestr); printVec(svec2); // aaa, bbb, ccc, ddd, xxx, aaa, aaa, svec2.erase(removedIter); printVec(svec2); // aaa, bbb, ccc, ddd, xxx, aaa, sort(svec2.begin(), svec2.end(), comparestr); // 可以传递一个自定义比较函数 printVec(svec2); // aaa, aaa, bbb, ccc, ddd, xxx, // 函数对象 string arr2[] = {"abc", "ab", "a"}; svec2 = vector<string>(arr2, arr2+3); stable_sort(svec2.begin(), svec2.end(), LessThan()); // 第三个参数就是函数对象 printVec(svec2); // a, ab, abc, // 函数对象的一般用法 string s1("abc"); string s2("ab"); LessThan lt; bool b = lt(s1, s2); // 比较size cout << "lt(s1,s2): " << (b?"true":"flase") << endl; // false。 因为s1的size大于s2的size // count_if string arr3[] = {"aaa", "bbbb", "ddddd", "cc"}; svec2 = vector<string>(arr3, arr3+4); int cnt = count_if(svec2.begin(), svec2.end(), GreaterThan(3)); // size大于3的元素个数 cout << "cnt=" << cnt << endl; // 2 cnt = count_if(svec2.begin(), svec2.end(), GreaterThan(2)); // size大于2的元素个数 cout << "cnt=" << cnt << endl; // 3 // remove vector<string>::iterator iter = remove(svec2.begin(), svec2.end(), "bbbb"); // 删除bbbb printVec(svec2); // aaa, ddddd, cc, cc, svec2.erase(iter, svec2.end()); printVec(svec2); // aaa, ddddd, cc, // for-each for_each(svec2.begin(), svec2.end(), PrintElem()); } int main() { fun(); return 0; } bool comparestr(const string& str1, const string& str2) { return str1.compare(str2) == 0; } void printVec(const vector<string>& svec) { vector<string>::const_iterator iter = svec.begin(); for (; iter != svec.end(); iter++) { cout << *iter << ", "; } cout << endl; }
三、函数对象
class CompareInt{ public : bool operator() (const int& i1, const int& i2) { return i1 < i2; } }; template<typename Type, class Comp> const Type& min3(const Type *p, int size, Comp comp) { int minIndex = 0; for (int i = 0; i < size; i++) { if (comp(p[i], p[minIndex])) { minIndex = i; } } return p[minIndex]; }
使用:
int arr[] = {4,3,1,2}; cout << "min number: " << min3(arr, 4, CompareInt()) << endl; // 1
四、一个取最小值函数的三种实现
// 函数模板 template <typename T> const T& min1(const T *p, int size) { int minIdx = 0; for (int i = 0; i < size; i++) { if (p[i] < p[minIdx]) { minIdx = i; } } return p[minIdx]; } // 函数指针 bool intComp(const int& i1, const int& i2) { return i1 < i2; } template <typename T> const T& min2(const T *p, int size, bool (*comp)(const T&, const T&) ){ int minIdx = 0; for (int i = 0; i < size; i++) { if (comp(p[i], p[minIdx])) { minIdx = i; } } return p[minIdx]; } // 函数对象 class Less{ public: bool operator()(const int &v1, const int &v2) { return v1 < v2; } }; template <typename T> const T& min3(const T *p, int size, Less less){ int minIdx = 0; for (int i = 0; i < size; i++) { if (less(p[i], p[minIdx])) { minIdx = i; } } return p[minIdx]; } void test () { int arr[] = {4,1,3,2}; cout << "min number: " << min1(arr, 4) << endl; cout << "min number: " << min2(arr, 4, intComp); cout << "min number: " << min3(arr, 4, Less()); }