5.Advanced concepts

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

TOP

原文地址:https://www.cnblogs.com/xin-le/p/4083876.html