《C++ Primer》 Part V (Advanced Topics)
1、异常捕获:
#include <iostream> #include <stdexcept> using namespace std; void fun(int i) { if(i<0) throw runtime_error("传入的参数不能是负数!"); cout<<"fun()"<<endl; } int main() { try { fun(-1); } catch(runtime_error& error) { cout<<error.what()<<endl; cout<<"异常处理完成。。。"<<endl; } std::cout<<"回到main()函数。。。"<<std::endl; }
结果:
2、使用预处理器进行调试:
#include <iostream> using namespace std; int main() { int i = -3; if(i >= 0) { cout<<"OK"<<endl; } else { #ifndef NDEBUG cout<<"i是负数!"<<endl; cout<<"错误信息:\t出错文件:"<<__FILE__<<"\t第 "<<__LINE__<<" 行\t发生在:"<<__DATE__<<" "<<__TIME__<<endl; #endif } }
希望显示DEBUG内容时,在编译时使用: g++ test.cpp -o test
不希望显示DEBUG内容时,在编译时使用: g++ test.cpp -o test -DNDEBUG ,切记,不是使用 -g 参数就是 DEBUG 模式!
预处理器还定义了其余四种在调试时非常有用的常量:
__FILE__ 文件名 __LINE__ 当前行号 __DATE__ 文件被编译的日期 __TIME__ 文件被编译的时间
结果:
3、使用 assert 来断言 "不可能发生" 的条件:
#include <cassert> int main() { int i = -1; assert(i>0); }
断言中条件如果为 false,会直接导致程序退出。
同样的,在编译时使用: g++ test.cpp -o test -DNDEBUG 则会忽略断言。
assert 对程序的调试有帮助,但不能用来代替运行时的逻辑检查,也不能代替对程序可能产生的错误的检测。
4、把输出重定向到文件:
#include <iostream> int main() { std::cout<<"cout"<<std::endl; std::cerr<<"cerr"<<std::endl; }
编译之后:g++ test.cpp -o test
./test >cout.log (等同于: ./test 1>cout.log) 把 cout 信息写入到文件中,不显示在屏幕上了。
./test 2>cout.log 把 cerr 信息写入到文件中,不显示在屏幕上了。
在一个程序里,可以约定好,把一些错误信息用 cerr 来输出,而 cout 只用来输出一些屏幕上比较需要的信息。
5、