c++学习点滴3

一、异常处理

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());
}






你可能感兴趣的:(C++)