理解虚函数(C++)

Eddy 发布于2011-4-20 17:9:4 分类: 程序设计 已浏览loading 网友评论0条 我要评论

         在编译时就确定函数地址的联编过程叫做静态联编。动态联编是指在程序编译时编译器并不知道函数的相对地址,调用函数的相对地址只有在程序运行时才能确定。

        比如下面代码中的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

关于 虚函数  C  的相关文章

记住我的信息,下次不用再输入 欢迎给Eddy Blog留言