友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!
深入浅出MFC第2版(PDF格式)-第20部分
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部! 如果本书没有阅读完,想下次继续接着阅读,可使用上方 "收藏到我的浏览器" 功能 和 "加入书签" 功能!
_afxExceptionLink。m_pException = e; } }
#else //_AFX_OLD_EXCEPTIONS
////////////////////////////////////////////////////////////////////////
// Exception macros using setjmp and longjmp
// (for portability to pilers with no support for C++ exception handling)
#define TRY
{ AFX_EXCEPTION_LINK _afxExceptionLink;
if (::setjmp(_afxExceptionLink。m_jumpBuf) == 0)
#define CATCH(class; e)
else if (::AfxCatchProc(RUNTIME_CLASS(class)))
{ class* e = (class*)_afxExceptionLink。m_pException;
#define AND_CATCH(class; e)
} else if (::AfxCatchProc(RUNTIME_CLASS(class)))
{ class* e = (class*)_afxExceptionLink。m_pException;
99
…………………………………………………………Page 162……………………………………………………………
第篇 勿在浮砂築高台
#define END_CATCH
} else { ::AfxThrow(NULL); } }
#define THROW(e) AfxThrow(e)
#define THROW_LAST() AfxThrow(NULL)
// Advanced macros for smaller code
#define CATCH_ALL(e)
else { CException* e = _afxExceptionLink。m_pException;
#define AND_CATCH_ALL(e)
} else { CException* e = _afxExceptionLink。m_pException;
#define END_CATCH_ALL } }
#define END_TRY }
#endif //_AFX_OLD_EXCEPTIONS
Template
这并不是一本C++ 书籍,我也并不打算介绍太多距离「运用MFC 」主题太远的C++ 论
题。Template 虽然很重要,但它与「运用MFC 」有什么关系?有!第8章当我们开始
设计Scribble 程序时,需要用到MFC 的collection classes ,而这一组类别自从MFC 3。0
以来就有了template 版本(因为Visual C++ 编译器从2。0 版开始支持C++ template)。
运用之前,我们总该了解一下新的语法、精神、以及应用。
好,到底什么是template?重要性如何?Kaare Christian 在1994/01/25 的PC…Magazine
上有一篇文章,说得很好:
无性生殖并不只是存在于遗传工程上,对程序员而言它也是一个由来已久的动作。过去,
我们只不过是以一个简单而基本的工具,也就是一个文字编辑器,重制我们的程序代码。
今天,C++ 提供给我们一个更好的繁殖方法:template 。
复制一段既有程序代码的一个最平常的理由就是为了改变数据类型。举个例子,假设你写
了一个绘图函数,使用整数x; y 坐标;突然之间你需要相同的程序代码,但坐标值改采
100
…………………………………………………………Page 163……………………………………………………………
第2章 C++ 的重要性伲�
long。你当然可以使用一个文字编辑器把这段码拷贝一份,然后把其中的数据类型改变
过来。有了C++,你甚至可以使用多载(overloaded )函数,那么你就可以仍旧使用相
同的函数名称。函数的多载的确使我们有比较清爽的程序代码,但它们意味着你还是必须
在你的程序的许多地方维护完全相同的算法。
C 语言对此问题的解答是:使用宏。虽然你因此对于相同的算法只需写一次程序代码,
但宏有它自己的缺点。第一,它只适用于简单的功能。第二个缺点比较严重:宏不
提供资料型别检验,因此牺牲了C++ 的一个主要效益。第三个缺点是:宏并非函数,
程序中任何调用宏的地方都会被编译器前置处理器原原本本地插入宏所定义的那一
段码,而非只是一个函数调用,因此你每使用一次宏,你的执行文件就会膨胀一点。
Templates 提供比较好的解决方案,它把「一般性的算法」和其「对资料型别的实作
部份」区分开来。你可以先写算法的程序代码,稍后在使用时再填入实际资料型别。新
的C++ 语法使「资料型别」也以参数的姿态出现。有了template ,你可以拥有宏「只
写一次」的优点,以及多载函数「类型检验」的优点。
C++ 的template 有两种,一种针对function,另一种针对class 。
Template Functions
假设我们需要一个计算数值幂次方的函数,名曰power 。我们只接受正幂次方数,如果
是负幂次方,就让结果为0 。
对于整数,我们的函数应该是这样:
#0001 int power(int base; int exponent)
#0002 {
#0003 int result = base;
#0004 if (exponent == 0) return (int)1;
#0005 if (exponent 《 0) return (int)0;
#0006 while (……exponent) result *= base;
#0007 return result;
#0008 }
101
…………………………………………………………Page 164……………………………………………………………
第篇 勿在浮砂築高台
对于长整数,函数应该是这样:
#0001 long power(long base; int exponent)
#0002 {
#0003 long result = base;
#0004 if (exponent == 0) return (long)1;
#0005 if (exponent 《 0) return (long)0;
#0006 while (……exponent) result *= base;
#0007 return result;
#0008 }
对于浮点数,我们应该。。。,对于复数,我们应该。。。。喔喔,为什么不能够把资料型别也变
成参数之一,在使用时指定呢?是的,这就是template 的妙用:
template T power(T base; int exponent);
写成两行或许比较清楚:
template
T power(T base; int exponent);
这样的函数声明是以一个特殊的template 前缀开始,后面紧跟着一个参数列(本例只一
个参数)。容易让人迷惑的是其中的〃class〃 字眼,它其实并不一定表示C++ 的class,
它也可以是一个普通的数据类型。 只不过是表示:T 是一种类型,而此一类型
将在调用此函数时才给予。
下面就是power 函数的template 版本:
#0001 template
#0002 T power(T base; int exponent)
#0003 {
#0004 T result = base;
#0005 if (exponent == 0) return (T)1;
#0006 if (exponent 《 0) return (T)0;
#0007 while (……exponent) result *= base;
#0008 return result;
#0009 }
传回值必须确保为类型T ,以吻合template 函数的声明。
下面是template 函数的调用方法:
102
…………………………………………………………Page 165……………………………………………………………
第2章 C++ 的重要性伲�
#0001 #include
#0002 void main()
#0003 {
#0004 int i = power(5; 4);
#0005 long l = power(1000L; 3);
#0006 long double d = power((long double)1e5; 2);
#0007
#0008 cout
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!