在编译时就确定函数地址的联编过程叫做静态联编。动态联编是指在程序编译时编译器并不知道函数的相对地址,调用函数的相对地址只有在程序运行时才能确定。 比如下面代码中的DisplayNumber()函数体内,编译器并不知道DisplayFormat(Number)调用的函数地址,真正的地址实在运行时通过实参传入的。 #include "stdio.h" #include "stdlib.h" //定义函数指针类型DISPLAYINTEGER,指向返回值为void,参数列表为(const int)的函数 typedef void( *DISPLAYINTEGER)(const int); //定义函数,将数字以十进制形式输出,该函数类型与DISPLAYINTEGER匹配 void DisplayDecimal(const int Number) { printf("The decimal value is %d\n",Number); } //定义函数,将数字以八进制形式输出,该函数类型与DISPLAYINTEGER匹配 void DisplayOctal(const int Number) { printf("The octal value is %o\n",Number); } //定义函数,将数字以十六进制形式输出,该函数类型与DISPLAYINTEGER匹配 void DisplayHexadecimal (const int Number) { printf("The hexadecimal value is %x\n",Number); } /******************************************************************** 定义通用的显示数字函数 DisplayFormat DISPLAYINTEGER函数指针类型,实参可以是以上定义的 三个函数之一。通过传递不同的实参,将数字以各种格式输出。 Number 准备输出的数字 ********************************************************************/ void DisplayNumber(DISPLAYINTEGER DisplayFormat,const int Number) { //调用以实参传入的函数,以某种格式输出整型数字 DisplayFormat(Number); } int main(int argc, char* argv[]) { int Number=0; // 如果有数字形式的命令行参数,将其输出,否则输出0 if(argc>1) Number=atoi(argv[1]); //分别以三种格式将数字输出 DisplayNumber(DisplayDecimal,Number); DisplayNumber(DisplayOctal,Number); DisplayNumber(DisplayHexadecimal,Number); return 0; } 在类的非静态成员函数前加关键字virtual,这一函数就是虚拟函数。编译器对于虚拟函数采用动态联编方式。通过虚函数的形式来实现上述代码: #include "stdafx.h" #include "stdio.h" #include "stdlib.h" //定义基类 class CDispDecimal { public: CDispDecimal(int i){Number=i;} CDispDecimal(){Number=0;} //虚函数 virtual DisplayFormat() { printf("The decimal value is %d\n",Number); } protected: int Number; }; //子类 class CDispOctal :public CDispDecimal { public: CDispOctal(int i){Number=i;} CDispOctal(){Number=0;} //重载 virtual DisplayFormat() { printf("The octal value is %o\n",Number); } }; //子类 class CDispHexadecimal :public CDispDecimal { public: CDispHexadecimal(int i){Number=i;} CDispHexadecimal(){Number=0;} //重载 virtual DisplayFormat() { printf("The hexadecimal value is %x\n",Number); } }; //通用函数,形参是基类的指针 void DisplayNumber(CDispDecimal* DisplayFOrmat) { DisplayFOrmat->DisplayFormat(); } int main(int argc, char* argv[]) { CDispDecimal Deci; CDispOctal Octa; CDispHexadecimal Hexa; if (argc>1) { Deci=atoi(argv[1]); Octa=atoi(argv[1]); Hexa=atoi(argv[1]); //分别以三种格式将数字输出 DisplayNumber(&Deci); DisplayNumber(&Octa); DisplayNumber(&Hexa); } return 0; } 上例定义的3个类分别封装了一种功能的实现,如果需要增加二进制格式的输出,只需再定义一个派生类CDispBinary,不必改性通用函数DisplayNumber()。
已经有(0)位网友发表了评论,你也评一评吧!
原创文章如转载,请注明:转载自Eddy Blog
原文地址:http://www.rrgod.com/program/764.html 欢迎订阅Eddy Blog。