赞
踩
1,预处理指令
C++的预处理(Preprocess),是指在C++程序源代码被编译之前,由预处理器(Preprocessor)对C++程序源代码进行的处理。这个过程并不对程序的源代码进行解析,但它把源代分割或处理成为特定的符号用来支持宏调调用。
常用指令:
#include 包含头文件
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");
}
最后结果显示:
一般来说,非类型模板参数可以是常整数(包括枚举)或者指向外部链接对象的指针。
那么就是说,浮点数是不行的,指向内部链接对象的指针是不行的。
template<typename T, int MAXSIZE>
class Stack{
Private:
T elems[MAXSIZE];
…
};
Int main()
{
Stack<int, 20> int20Stack;
Stack<int, 40> int40Stack;
…
};
C++编程语言中的模板应用在一定程度上大大提高了程序开发的效率。我们在这篇文章中为大家详细讲解一下有关C++模板的基本概念,希望初学者们可以通过本文介绍的内容充分掌握这方面的知识。
前段时间重新学习C++,主要看C++编程思想和C++设计新思维。对模版的使用有了更进一层的了解,特总结如下:
下面列出了C++模板的常用情况:
1. C++模板类静态成员
- template < typename T> struct testClass
- {
- static int _data;
- };
- template< > int testClass< char>::_data = 1;
- template< > int testClass< long>::_data = 2;
- int main( void ) {
- cout < < boolalpha < < (1==testClass< char>::_data) < < endl;
- cout < < boolalpha < < (2==testClass< long>::_data) < < endl;
- }
2. C++模板类偏特化
- template < class I, class O> struct testClass
- {
- testClass() { cout < < "I, O" < < endl; }
- };
- template < class T> struct testClass< T*, T*>
- {
- testClass() { cout < < "T*, T*" < < endl; }
- };
- template < class T> struct testClass< const T*, T*>
- {
- testClass() { cout < < "const T*, T*" < < endl; }
- };
- int main( void )
- {
- testClass< int, char> obj1;
- testClass< int*, int*> obj2;
- testClass< const int*, int*> obj3;
- }
3.类模版+函数模版
- template < class T> struct testClass
- {
- void swap( testClass< T>& ) { cout < < "swap()" < < endl; }
- };
- template < class T> inline void swap( testClass< T>& x,
testClass< T>& y )- {
- x.swap( y );
- }
- int main( void )
- {
- testClass< int> obj1;
- testClass< int> obj2;
- swap( obj1, obj2 );
- }
4. 类成员函数模板
- struct testClass
- {
- template < class T> void mfun( const T& t )
- {
- cout < < t < < endl;
- }
- template < class T> operator T()
- {
- return T();
- }
- };
- int main( void )
- {
- testClass obj;
- obj.mfun( 1 );
- int i = obj;
- cout < < i < < endl;
- }
5. 缺省C++模板参数推导
- template < class T> struct test
- {
- T a;
- };
- template < class I, class O=test< I> > struct testClass
- {
- I b;
- O c;
- };
- void main()
- {
- }
6. 非类型C++模板参数
- template < class T, int n> struct testClass {
- T _t;
- testClass() : _t(n) {
- }
- };
- int main( void ) {
- testClass< int,1> obj1;
- testClass< int,2> obj2;
- }
7. 空模板参数
- template < class T> struct testClass;
- template < class T> bool operator==( const testClass< T>&,
const testClass< T>& )- {
- return false;
- };
- template < class T> struct testClass
- {
- friend bool operator== < >
( const testClass&, const testClass& );- };
- void main()
- {
- }
8. template template 类
- struct Widget1
- {
- template< typename T>
- T foo(){}
- };
- template< template< class T>class X>
- struct Widget2
- {
- };
- void main()
- {
- 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;
其实这和定义结构体类型非常相似,不过很少有人这么使用。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。