The codes:
// 5. Advanced Concepts /******************************************************** 1 Templates */ // function template #include <iostream> using namespace std; template <class T> T GetMax (T a, T b) { T result; result = (a>b)? a : b; return (result); } int main () { int i=5, j=6, k; long l=10, m=5, n; k=GetMax<int>(i,j); n=GetMax<long>(l,m); cout << k << endl; cout << n << endl; return 0; } // function template, test parameter #include <iostream> using namespace std; template <class T> // T is template parameter T GetMax (T a, T b) { T result; result = (a>b)? a : b; return (result); } int main () { int i=5, j=6, k; long l=10, m=5, n; double d=12.9; k=GetMax<int>(i,d); // 参数传递时,会强制类型转化。会提出警告 n=GetMax<long>(l,m); cout << k << endl; cout << n << endl; return 0; } // function template II #include <iostream> using namespace std; template <class T> T GetMax (T a, T b) { return (a>b?a:b); } int main () { int i=5, j=6, k; long l=10, m=5, n; k=GetMax(i,j); // 自动识别参数及返回类型。这时如把j改成实数,会通不过编译 n=GetMax(l,m); // 因为找不到合适函数 cout << k << endl; cout << n << endl; return 0; } // two different types #include <iostream> using namespace std; template <class T, class U> T GetMax (T a, U b) { //但返回类型只能用一个 return (a>b?a:b); } int main () { int i=5, k; long m=5, n; double d=12.9; k=GetMax(i,d); // 测试不同参数类型 n=GetMax(d,m); // 能运行,有警告 cout << k << endl; cout << n << endl; return 0; } // class templates #include <iostream> using namespace std; template <class T> class mypair { T a, b; public: mypair (T first, T second) {a=first; b=second;} T getmax (); }; template <class T> // must always use this template<... T mypair<T>::getmax () { T retval; retval = a>b? a : b; return retval; } int main () { mypair <int> myobject (100, 75); // int is template parameter cout << myobject.getmax(); return 0; } // template specialization #include <iostream> using namespace std; // class template: template <class T> class mycontainer { T element; public: mycontainer (T arg) {element=arg;} T increase () {return ++element;} }; // class template specialization: 模板特化,指指定数据类型 template <> class mycontainer <char> { char element; public: mycontainer (char arg) {element=arg;} char uppercase () { if ((element>='a')&&(element<='z')) element+='A'-'a'; return element; } }; int main () { mycontainer<int> myint (7); mycontainer<char> mychar ('j'); cout << myint.increase() << endl; cout << mychar.uppercase() << endl; return 0; } // sequence template #include <iostream> using namespace std; template <class T, int N> class mysequence { T memblock [N]; public: void setmember (int x, T value); T getmember (int x); }; template <class T, int N> void mysequence<T,N>::setmember (int x, T value) { memblock[x]=value; } template <class T, int N> T mysequence<T,N>::getmember (int x) { return memblock[x]; } int main () { mysequence <int,5> myints; mysequence <double,5> myfloats; myints.setmember (0,100); myfloats.setmember (3,3.1416); cout << myints.getmember(0) << ' '; cout << myfloats.getmember(3) << ' '; return 0; } /********************************************* 2 Namespaces */ // namespaces #include <iostream> using namespace std; namespace first { int var = 5; } namespace second { double var = 3.1416; } int main () { cout << first::var << endl; cout << second::var << endl; return 0; } // using #include <iostream> using namespace std; namespace first { int x = 5; int y = 10; } namespace second { double x = 3.1416; double y = 2.7183; } int main () { using first::x; using second::y; cout << x << endl; cout << y << endl; cout << first::y << endl; cout << second::x << endl; return 0; } // using #include <iostream> using namespace std; namespace first { int x = 5; int y = 10; } namespace second { double x = 3.1416; double y = 2.7183; } int main () { using namespace first; cout << x << endl; cout << y << endl; cout << second::x << endl; cout << second::y << endl; return 0; } // using -- 修改。同名的情况,要有个覆盖规则,不知道是什么? // 作用域,与函数中的同名变量一样。 #include <iostream> using namespace std; namespace first { int x = 5; int y = 10; } namespace second { double x = 3.1416; double y = 2.7183; } int main () { int x = 3; using namespace first; cout << x << endl; cout << y << endl; cout << second::x << endl; cout << second::y << endl; return 0; } // using namespace example #include <iostream> using namespace std; namespace first { int x = 5; } namespace second { double x = 3.1416; } int main () { { using namespace first; cout << x << endl; } { using namespace second; cout << x << endl; } return 0; } /************************************************* 3 Exceptions */ // exceptions #include <iostream> using namespace std; int main () { try { throw 20; } catch (int e) { cout << "An exception occurred. Exception Nr. " << e << endl; } return 0; } // default handler #include <iostream> #include <string> using namespace std; int main () { string s; try { cin >> s; if( s.length()>1 || s.length()<1 ) throw s; else throw s[0]; } catch( char param ) { cout << "This is a char." << endl; } catch(...) { cout << "default exception, string" << endl; } return 0; } // nest try-catch 注意一点:throw的类型与catch的参数,要对应上 //否则可能不会有语法错误,但错误是捕捉不到了 #include <iostream> #include <string> using namespace std; int main () { string s; try { cin >> s; try{ if( 1==s.length() ) throw s[0]; // s[0] 改成 s 试试? } catch( char c ) { cout << "The char is: " << c << endl; } if( s.length()>1 ) throw s; } catch(...) { cout << "default exception, string" << endl; } return 0; } // standard exceptions #include <iostream> #include <exception> using namespace std; class myexception: public exception { virtual const char* what() const throw() { return "My exception happened"; } } myex; int main () { try { throw myex; } catch (exception& e) // & { cout << e.what() << endl; } return 0; } // bad_alloc standard exception #include <iostream> #include <exception> using namespace std; int main () { try { int* myarray= new int[1000]; } catch (exception& e) { cout << "Standard exception: " << e.what() << endl; } return 0; } /******************************************************* 4 Type Casting */ // class type-casting #include <iostream> using namespace std; class CDummy { float i,j; }; class CAddition { int x,y; public: CAddition (int a, int b) { x=a; y=b; } int result() { return x+y;} }; int main () { CDummy d; CAddition * padd; padd = (CAddition*) &d; cout << padd->result(); return 0; } // dynamic_cast #include <iostream> #include <exception> using namespace std; class CBase { virtual void dummy() {} }; class CDerived: public CBase { int a; }; int main () { try { CBase * pba = new CDerived; CBase * pbb = new CBase; CDerived * pd; pd = dynamic_cast<CDerived*>(pba); if (pd==0) cout << "Null pointer on first type-cast" << endl; pd = dynamic_cast<CDerived*>(pbb); if (pd==0) cout << "Null pointer on second type-cast" << endl; } catch (exception& e) {cout << "Exception: " << e.what();} return 0; } // const_cast #include <iostream> using namespace std; void print (char * str) { cout << str << endl; } int main () { const char * c = "sample text"; print ( const_cast<char *> (c) ); //print( c ); return 0; } // typeid #include <iostream> #include <typeinfo> using namespace std; int main () { int * a,b; a=0; b=0; if (typeid(a) != typeid(b)) { cout << "a and b are of different types: "; cout << "a is: " << typeid(a).name() << ' '; cout << "b is: " << typeid(b).name() << ' '; } return 0; } // typeid, polymorphic class #include <iostream> #include <typeinfo> #include <exception> using namespace std; class CBase { virtual void f(){} }; class CDerived : public CBase {}; int main () { try { CBase* a = new CBase; CBase* b = new CDerived; cout << "a is: " << typeid(a).name() << ' '; cout << "b is: " << typeid(b).name() << ' '; cout << "*a is: " << typeid(*a).name() << ' '; cout << "*b is: " << typeid(*b).name() << ' '; } catch (exception& e) { cout << "Exception: " << e.what() << endl; } return 0; } /********************************************************* 5. preprocessor directives 预处理指令 */ // function macro #include <iostream> using namespace std; #define getmax(a,b) ((a)>(b)?(a):(b)) int main () { int x=5, y; y=getmax(x,2); cout << y << endl; cout << getmax(7,x) << endl; return 0; } // standard macro names #include <iostream> using namespace std; int main () { cout << "This is the line number " << __LINE__; cout << " of file " << __FILE__ << ". "; cout << "Its compilation began " << __DATE__; cout << " at " << __TIME__ << ". "; cout << "The compiler gives a __cplusplus value of "; cout << __cplusplus << endl; return 0; }