惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

L
LangChain Blog
V
V2EX
爱范儿
爱范儿
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Martin Fowler
Martin Fowler
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Apple Machine Learning Research
Apple Machine Learning Research
WordPress大学
WordPress大学
有赞技术团队
有赞技术团队
宝玉的分享
宝玉的分享
Last Week in AI
Last Week in AI
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
罗磊的独立博客
小众软件
小众软件
Vercel News
Vercel News
博客园 - 司徒正美
阮一峰的网络日志
阮一峰的网络日志
V
Visual Studio Blog
J
Java Code Geeks
P
Proofpoint News Feed
MongoDB | Blog
MongoDB | Blog
B
Blog
美团技术团队
量子位

博客园 - 青青木

ASP.net2.0把word、excel转换成Html(转) 在三层交换机上开专线IP的方法 [转]静态框架导航,左侧折叠树的样式,类似于treeview 在ASP.NET中使用FCKEditor的简单配置方法 Matlab与Access数据库的连接 [转]用matlab做聚类分析 Word 2003特殊符号录入与编辑(转) C++内存分配的五种的区别(转) C#中正则表达式的完全匹配 插入SQL语句后,返回刚插入记录的ID asp.net定义用户控件时,属性持久化和如何动态加载的问题 命名空间“Microsoft office”中不存在类型或命名空间名称“Interop” GridView相应模板列中的LinkButton按钮的事件 visual studio 2005 和 sql server 2005 安装时需要注意的事项 使用ConfigurationManager需要在.net引用中添加System.Configuration引用 还原数据库后,用户名出错,不能修改用户属性 DataView设置datasource后,需要databind() asp.net中重命名网页的一种方法 vc中出现“没有找到mspdb60.dll文件”时 ,解决方法
C++语言中的虚函数
青青木 · 2008-01-14 · via 博客园 - 青青木

    在面向对象的C++语言中,虚函数(virtual function)是一个非常重要的概念。因为它充分体现了面向对象思想中的继承和多态性这两大特性,在C++语言里应用极广。比如在微软的MFC类库中,你会发现很多函数都有virtual关键字,也就是说,它们都是虚函数。难怪有人甚至称虚函数是C++语言的精髓。
    什么是虚函数呢,我们先来看看微软的解释: 
    虚函数是指一个类中你希望重载的成员函数,当你用一个基类指针或引用指向一个继承类对象的时候,你调用一个虚函数,实际调用的是继承类的版本。
    这个定义说得不是很明白。MSDN中还给出了一个例子,但是它的例子也并不能很好的说明问题。我们自己编写这样一个例子:
    

class Parent
{
    
public:
      
char data[20];
      
void Parent::Function1()
      {
          printf(
"This is parent,function1\n");
      }
      
virtual void Function2()   // 这里声明Function2是虚函数
      {
       printf(
"This is parent,function2\n");
      }
}
class Child:public Parent
{
  
void Function1()
  {
      printf(
"This is child,function1\n");
  }
  
  
void Function2()
  {
      printf(
"This is child,function2\n");
  }
}
int main(int argc, char* argv[])
{
  Parent 
*p;  // 定义一个基类指针
  if(_getch()=='c')     // 如果输入一个小写字母c
       p=&child;         // 指向继承类对象
  else
       p
=&parent;       // 否则指向基类对象
  p->Function1();   // 这里在编译时会直接给出Parent::Function1()的入口地址。                                 
  p->Function2();    // 注意这里,执行的是哪一个Function2?
  return 0;
}


用任意版本的Visual C++Borland C++编译并运行,输入一个小写字母c,得到下面的结果:

This is parent,function1

This is child,function2

      为什么会有第一行的结果呢?因为我们是用一个Parent类的指针调用函数Fuction1(),虽然实际上这个指针指向的是Child类的对象,但编译器无法知道这一事实(直到运行的时候,程序才可以根据用户的输入判断出指针指向的对象),它只能按照调用Parent类的函数来理解并编译,所以我们看到了第一行的结果。

        那么第二行的结果又是怎么回事呢?我们注意到,Function2()函数在基类中被virtual关键字修饰,也就是说,它是一个虚函数。虚函数最关键的特点是“动态联编”,它可以在运行时判断指针指向的对象,并自动调用相应的函数。如果我们在运行上面的程序时任意输入一个非c的字符,结果如下:

This is parent,function1

This is parent,function2

        请注意看第二行,它的结果出现了变化。程序中仅仅调用了一个Function2()函数,却可以根据用户的输入自动决定到底调用基类中的Function2还是继承类中的Function2,这就是虚函数的作用。我们知道,在MFC中,很多类都是需要你继承的,它们的成员函数很多都要重载,比如编写MFC应用程序最常用的CView::OnDraw(CDC*)函数,就必须重载使用。把它定义为虚函数(实际上,在MFCOnDraw不仅是虚函数,还是纯虚函数),可以保证时刻调用的是用户自己编写的OnDraw。虚函数的重要用途在这里可见一斑。