阅读C++源码必备

1,预处理指令

C++的预处理(Preprocess),是指在C++程序源代码被编译之前,由预处理器(Preprocessor)对C++程序源代码进行的处理。这个过程并不对程序的源代码进行解析,但它把源代分割或处理成为特定的符号用来支持宏调调用。

常用指令:

      #include 包含头文件

       #if 条件
  #else 否则
  #elif 否则如果
  #endif 结束条件
  #ifdef 或 #if defined 如果定义了一个符号, 就执行操作
  #ifndef 或 #if !defined 如果没有定义一个符号,就指执行操作
  #define 定义一个符号
  #undef 删除一个符号
  #line 重新定义当前行号和文件名
  #error 输出编译错误 消息, 停止编译
  #pragma 提供 机器专用的特性,同时保证与C++的完全兼容

2,模板用法 :

template:酷勤

1. 模板的概念。

我们已经学过重载(Overloading),对重载函数而言,C++的检查机制能通过函数参数的不同及所属类的不同。正确的调用重载函数。例如,为求两个数的最大值,我们定义MAX()函数需要对不同的数据类型分别定义不同重载(Overload)版本。

//函数1.

int max(int x,int y);
{return(x>y)?x:y ;}

//函数2.
float max( float x,float y){
return (x>y)? x:y ;}

//函数3.
double max(double x,double y)
{return (c>y)? x:y ;}

但如果在主函数中,我们分别定义了 char a,b; 那么在执行max(a,b);时 程序就会出错,因为我们没有定义char类型的重载版本。

现在,我们再重新审视上述的max()函数,它们都具有同样的功能,即求两个数的最大值,能否只写一套代码解决这个问题呢?这样就会避免因重载函数定义不 全面而带来的调用错误。为解决上述问题C++引入模板机制,模板定义:模板就是实现代码重用机制的一种工具,它可以实现类型参数化,即把类型定义为参数, 从而实现了真正的代码可重用性。模版可以分为两类,一个是函数模版,另外一个是类模版。

2.   函数模板的写法

函数模板的一般形式如下:

Template <class或者也可以用typename T>

返回类型 函数名(形参表)
{//
函数定义体 }

说明: template是一个声明模板的关键字,表示声明一个模板关键字class不能省略,如果类型形参多余一个 ,每个形参前都要加class <类型 形参表>可以包含基本数据类型可以包含类类型.

请看以下程序:

//Test.cpp

#include <iostream>

using std::cout;

using std::endl;

//声明一个函数模版,用来比较输入的两个相同数据类型的参数的大小,class也可以被typename代替,

//T可以被任何字母或者数字代替。

template <class T>

T min(T x,T y)

return(x<y)?x:y;}

void main( )

{

     int n1=2,n2=10;

     double d1=1.5,d2=5.6;

     cout<< "较小整数:"<<min(n1,n2)<<endl;

     cout<< "较小实数:"<<min(d1,d2)<<endl;

     system("PAUSE");

}

程序运行结果: 

 

程序分析:main()函数中定义了两个整型变量n1 , n2 两个双精度类型变量d1 , d2然后调用min( n1, n2); 即实例化函数模板T min(T x, T y)其中T为int型,求出n1,n2中的最小值.同理调用min(d1,d2)时,求出d1,d2中的最小值.

3. 类模板的写法

定义一个类模板:

Template < class或者也可以用typename T >
class类名{
//类定义......
};

说明:其中,template是声明各模板的关键字,表示声明一个模板,模板参数可以是一个,也可以是多个。

例如:定义一个类模板:

// ClassTemplate.h
#ifndef ClassTemplate_HH

#define ClassTemplate_HH

template<typename T1,typename T2>

class myClass{

private:

     T1 I;

     T2 J;

public:

     myClass(T1 a, T2 b);//Constructor

     void show();

};

//这是构造函数

//注意这些格式

template <typename T1,typename T2>

myClass<T1,T2>::myClass(T1 a,T2 b):I(a),J(b){}

//这是void show();

template <typename T1,typename T2>

void myClass<T1,T2>::show()

{

     cout<<"I="<<I<<", J="<<J<<endl;

}

#endif

// Test.cpp

#include <iostream>

#include "ClassTemplate.h"

using std::cout;

using std::endl;

void main()

{

     myClass<int,int> class1(3,5);

     class1.show();

     myClass<int,char> class2(3,"a");

     class2.show();

     myClass<double,int> class3(2.9,10);

     class3.show();

     system("PAUSE");

}

最后结果显示:

 

4.非类型模版参数

一般来说,非类型模板参数可以是常整数(包括枚举)或者指向外部链接对象的指针。

那么就是说,浮点数是不行的,指向内部链接对象的指针是不行的。


template<typename T, int MAXSIZE>

class Stack{

Private:

       T elems[MAXSIZE];

};

Int main()

{

       Stack<int, 20> int20Stack;

       Stack<int, 40> int40Stack;

};

 51CTO网站 http://developer.51cto.com/art/201002/182202.htm  

C++编程语言中的模板应用在一定程度上大大提高了程序开发的效率。我们在这篇文章中为大家详细讲解一下有关C++模板的基本概念,希望初学者们可以通过本文介绍的内容充分掌握这方面的知识。

前段时间重新学习C++,主要看C++编程思想和C++设计新思维。对模版的使用有了更进一层的了解,特总结如下:

下面列出了C++模板的常用情况:

1. C++模板类静态成员

  
  
  
  
  1. template < typename T> struct testClass   
  2. {   
  3. static int _data;   
  4. };   
  5. template< > int testClass< char>::_data = 1;   
  6. template< > int testClass< long>::_data = 2;   
  7. int main( void ) {   
  8. cout < <  boolalpha < <  (1==testClass< char>::_data) < <  endl;   
  9. cout < <  boolalpha < <  (2==testClass< long>::_data) < <  endl;   
  10. }  

2. C++模板类偏特化

  
  
  
  
  1. template < class I, class O> struct testClass   
  2. {   
  3. testClass() { cout < <  "I, O" < <  endl; }   
  4. };   
  5. template < class T> struct testClass< T*, T*>   
  6. {   
  7. testClass() { cout < <  "T*, T*" < <  endl; }   
  8. };   
  9. template < class T> struct testClass< const T*, T*>   
  10. {   
  11. testClass() { cout < <  "const T*, T*" < <  endl; }   
  12. };   
  13. int main( void )   
  14. {   
  15. testClass< int, char> obj1;   
  16. testClass< int*, int*> obj2;   
  17. testClass< const int*, int*> obj3;   

3.类模版+函数模版

  
  
  
  
  1. template < class T> struct testClass   
  2. {   
  3. void swap( testClass< T>& ) { cout < <  "swap()" < <  endl; }   
  4. };   
  5. template < class T> inline void swap( testClass< T>& x, 
    testClass
    < T>& y )   
  6. {   
  7. x.swap( y );   
  8. }   
  9. int main( void )  
  10. {   
  11. testClass< int> obj1;   
  12. testClass< int> obj2;   
  13. swap( obj1, obj2 );   

4. 类成员函数模板

  
  
  
  
  1. struct testClass  
  2. {   
  3. template < class T> void mfun( const T& t )  
  4. {   
  5. cout < <  t < <  endl;   
  6. }   
  7. template < class T> operator T()   
  8. {   
  9. return T();   
  10. }   
  11. };   
  12. int main( void )   
  13. {   
  14. testClass obj;   
  15. obj.mfun( 1 );   
  16. int i = obj;   
  17. cout < <  i < <  endl;   

5. 缺省C++模板参数推导

  
  
  
  
  1. template < class T> struct test   
  2. {   
  3. T a;   
  4. };   
  5. template < class I, class O=test< I> > struct testClass   
  6. {   
  7. I b;   
  8. O c;   
  9. };   
  10. void main()  
  11. {  

6. 非类型C++模板参数

  
  
  
  
  1. template < class T, int n> struct testClass {   
  2. T _t;   
  3. testClass() : _t(n) {   
  4. }   
  5. };   
  6. int main( void ) {   
  7. testClass< int,1> obj1;   
  8. testClass< int,2> obj2;   

7. 空模板参数

  
  
  
  
  1. template < class T> struct testClass;   
  2. template < class T> bool operator==( const testClass< T>&, 
    const testClass
    < T>& )   
  3. {   
  4. return false;   
  5. };   
  6. template < class T> struct testClass   
  7. {   
  8. friend bool operator== < >
    ( const testClass&, const testClass& );   
  9. };   
  10. void main()  
  11. {  

8. template template 类

  
  
  
  
  1. struct Widget1   
  2. {   
  3. template< typename T>   
  4. T foo(){}   
  5. };   
  6. template< template< class T>class X>   
  7. struct Widget2  
  8. {   
  9. };   
  10. void main()  
  11. {  
  12. cout< <  3 < <  '\n';  

以上就是对C++模板的一些常用方法的介绍。


3,typedef

http://www.cnblogs.com/SweetDream/archive/2006/05/10/395921.html

C/C++语言中的typedef相信大家已经不陌生,本文对C/C++语言关键字typedef的各种用法作一个介绍。

typedef,顾名思义,为“类型定义”,可以解释为:将一种数据类型定义为某一个标识符,在程序中使用该标识符来实现相应数据类型变量的定义。例如:

 

typedef unsigned int UINT;

int main (int argc, char *argv[])

{

    unsigned int a;   // it’s OK

    UINT b; // it’s OK, a and b are of the same type (int)

    // . . .    // code references the symbol a and b

    return 0;

}

 

上面的代码中,a和b属于同一种数据类型(unsigned int型),因为UINT标识符已经标示为unsigned int类型。上面的代码看似简单,相信很多读者都用过这种方法,但这绝不是typedef的全部,下面介绍使用typedef定义复杂数据类型的几种用法。

 

1、 定义结构体类型

结构体是一种较为常见的数据类型,在C/C++程序设计中使用的非常广泛。下面的代码就是结构体类型的一个应用:

#include <iostream.h>

int main (int argc, char *argv[])

{

    struct {int x; int y;} point_a, point_b;

    point_a.x = 10; point_a.y = 10;

    point_b.x = 0; point_b.y = 0;

    ios::sync_with_stdio();

    cout << point_a.x + point_a.y << endl;

    cout << point_b.x + point_b.y << endl;

    return 0;

}

上面的代码包含了两个结构体变量:point_a和point_b,它们的数据类型相同,都是struct {int x; int y;}类型。这种说法可能有点别扭,习惯上说point_a和point_b都是结构体类型,为什么偏偏要说是struct {int x; int y;}类型呢?因为这种说法更加精确。比如在第一个例子中,对于“unsigned int a, b;”这条语句,我们可以说a和b都是整数类型,但更精确地说,它们应该是unsigned int类型。

既然struct {int x; int y;}是一种自定义的复杂数据类型,那么如果我们要定义多个struct {int x; int y;}类型的变量,应该如何编写代码呢?其实很简单,就当struct {int x; int y;}是一个简单数据类型就可以了:

struct {int x; int y;} var_1;   // 定义了变量var_1

struct {int x; int y;} array_1 [10];    // 定义了数组array_1

struct {struct{int x; int y;} part1; int part2;} cplx;

上面的第三行定义了一个cplx变量,它的数据类型是一个复杂的结构体类型,有两个成员:part1和part2。part1是struct {int x; int y;}类型的,part2是int类型的。

从上面的例子可以看出,如果在程序中需要多处定义struct {int x; int y;}类型的变量,就必须多次输入“struct {int x; int y;}”这一类型名称,况且,如果在结构体中有某个成员是struct {int x; int y;}类型的,还会使得定义变得非常繁杂而且容易出错。为了输入程序的方便,同时为了增强程序的可读性,我们可以把struct {int x; int y;}这一数据类型定义为标识符“Point”,那么上面的程序就会变得更容易理解:

typedef struct {int x; int y;} Point;

Point var_1; // 定义了变量var_1

Point array_1 [10]; // 定义了数组array_1

struct {Point part1; int part2;} cplx; // 定义了复杂类型变量cplx

需要说明的是,我们还可以使用下面的方法来定义结构体变量:

struct t_Point {

    int x; int y;};    // 注意,这里最后一个分号不能省略

 

int main(int argc, char* argv[])

{

    struct t_Point a, b;

    // . . .

    return 0;

}

显然,这种方法没有typedef更加直观(在C++中,main函数第一行的struct关键字可以省略,但在标准C中,省略该关键字会出现编译错误)。

此外,对于定义链接队列中的结点,我们可以这样实现:

typedef struct t_node {

    int Value;

    struct t_node *next;

} Node;

当然也可以这样定义:

typedef strcut t_node Node;

struct t_node {

    int Value;

    Node *next;

};

 

2、定义数组类型

与定义结构体类型相似,可以使用typedef来定义数组类型,例如:

typedef int MyIntArray [100];

那么程序中的

MyIntArray ia;

就相当于

int ia[100];

3、 定义函数指针

看下面的代码:

typedef void (*FUNCADDR)(int)

此处FUNCADDR是指向这样一个函数的指针,该函数的返回值为void类型,函数有一个int型的参数。再例如:

void print (int x)

{

    printf (“%d\n”, x);

}

int main (int argc, char *argv[])

{

    FUNCADDR pFunc;

    pFunc = print;  // 将指针指向print函数

    (*pFunc)(25);       // 调用函数print

    return 0;

}

函数指针一般用于回调函数、中断处理过程的声明,以及在面向对象程序设计中对事件处理过程的声明。

4、 定义类类型

类是面向对象程序设计语言中引入的一种新的数据类型,既然是数据类型,就可以使用typedef对其进行定义:

typedef class {

    private:

        int a;

    public:

        int b;

} MyClass;

其实这和定义结构体类型非常相似,不过很少有人这么使用。


你可能感兴趣的:(阅读C++源码必备)