一、异常处理
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());
}
分享到:
相关推荐
个人认为比较经典(作者:用了几年java 了,突然想学习c++ ,昨天用了一天的时间疯狂的学习了一天c++ 基础知识,发现感觉还不错,不过精验告诉我,学编程语言一定要实践,在这里指记录了一些学习中的点滴。...
压缩包里面包含多个目录,包含了多种查找算法、递归的示例、堆栈使用、队列、二叉树、各种...此资源都是我在学习C++过程中写的代码,记录了学习过程中的点滴,希望对你有帮助,比较适合C++初学者或者数据结构初学者。
学习编程的软件其实挺多的,这⾥主要跟⼤家介绍C/C++,Java,Python,前端⽹页,Linux这5个⽅⾯,希望能帮到想利⽤点滴看⼿机 的时间学习的你 1、C/C++ 这⾥介绍⼀个软件—C++编译器(c4droid),可以直接编辑运⾏C/...
C_C++程序设计教程.面向对象分册(第2版)[郑秋生][电子教案]
好资源共享,希望对你的学习能有点滴的帮助.
在IAR中编程序时时常用到自己编写的头文件,这时需要设置添加包含头文件的路径的。常用方法是在工程上单击右键选择options,在c/c++ complier 设置里面的preprocessor中加载你的头文件路径。
这个是图的基本操作,希望能够帮助正在学习数据结构的你
包含kdevelop使用手册,KDevelop编程环境教程,kdevelop的点滴收获,kdevelop应用实例,Linux下C开发环境的构成和安装,安装KDevelop开发第一个C-C++程序,走进Linux编程的大门,Linux开发环境必备十大开发工具等...
https://pan.baidu.com/s/1dEUQRRz#list/path=/ 这个是百度云链接的地址 CSDN 不允许0分下载了,只好先择最低的 2 分了
MFC的TabCtrl控件,是我们在项目中常用的,它可以实现界面切换的效果,作为小白,在学习的过程中记录自己的点滴过程,对自己也是一种成长。
4.3 C、C++的学习方式 187 4.3.1 从BASIC到C 187 4.3.2 C、汇编、API的关系 187 4.3.3 接口的建立方法 190 4.4 挂钩技术 201 4.4.1 Windows上C的挂钩 201 4.4.2 C++的挂钩技术 213 第5章 代码的规范和风格 220 5.1 ...
4.3 C、C++的学习方式 187 4.3.1 从BASIC到C 187 4.3.2 C、汇编、API的关系 187 4.3.3 接口的建立方法 190 4.4 挂钩技术 201 4.4.1 Windows上C的挂钩 201 4.4.2 C++的挂钩技术 213 第5章 代码的规范和风格 220 5.1 ...
此代码仓库本质上是由多个有代表性的子项目整合而成的超级集索引,这里记录了我自学习编程以来所学所做的冰山一角。 相关的子项目代码目前以 C/C++、Java、Python 为主。涉及到的领域谈不上包罗万象,但毕竟是我多年...
Android系统开发工程师常常需要深入理解系统的运转过程,而本书所涉及的内容可能正是他们在工作和学习中最想了解的。那些对具体模块(如Audio系统和Surface系统)感兴趣的读者 也可以直接阅读相关章节的内容。 ...
C++ 泛型编程系列讲座之实施 泛型技巧系列:简单类型选择器 C# 泛型简介 我眼中的C#2.0新功能特性 泛型技巧系列:避免基类及接口约束 New Article 不该用Generics实现Abstract Factory的理由 C#2.0-泛型 C#2.0-...