zoukankan      html  css  js  c++  java
  • c++中virtual 虚函数

    转载:

    https://www.cnblogs.com/weiyouqing/p/7544988.html

    在面向对象的C++语言中,虚函数(virtual function)是一个非常重要的概念。

    什么是虚函数:

      虚函数是指一个类中你希望重载的成员函数 ,当你用一个  基类指针或引用   指向一个继承类对象的时候,调用一个虚函数时, 实际调用的是继承类的版本。  ——摘自MSDN

    #include <iostream>
    using  namespace std;
    
    class Parent
    {    
     public:
         
         char data[20];
         void Function1();    
         virtual void Function2();   // 这里声明Function2是虚函数
         
     }parent;
     
     void Parent::Function1()
     {
         printf("This is parent,function1
    ");
     }
     
     void Parent::Function2()
     {
         printf("This is parent,function2
    ");
     }
     
     class Child:public Parent
     {
         void Function1();
         void Function2();
         
     } child;
     
     void Child::Function1()
     {
         printf("This is child,function1
    ");
     }
     
     void Child::Function2()
     
     {
         printf("This is child,function2
    ");
     }
     
     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,得到下面的结果:
    1 This is parent,function1
    2 This is child,function2
    为什么会有第一行的结果呢?
    因为我们是用一个Parent类的指针调用函数Fuction1(),虽然实际上这个指针指向的是Child类的对象,但编译器无法知道这一事实(直到运行的时候,程序才可以根据用户的输入判断出指针指向的对象),它只能按照调用Parent类的函数来理解并编译,所以我们看到了第一行的结果。 那么第二行的结果又是怎么回事呢?我们注意到,Function2()函数在基类中被virtual关键字修饰,也就是说,它是一个虚函数。
    虚函数最关键的特点是“动态联编”,它可以在运行时判断指针指向的对象,并自动调用相应的函数。


    如果我们在运行上面的程序时任意输入一个非c的字符,结果如下:
    1 This is parent,function1
    2 This is parent,function2
    请注意看第二行,它的结果出现了变化。程序中仅仅调用了一个Function2()函数,却可以根据用户的输入自动决定到底调用基类中的Function2还是继承类中的Function2,这就是虚函数的作用。
    PS:一定要注意“静态联翩 ”和“ 动态联编 ”的区别;对于我来说,若没有在VC6.0中亲自去测试,凭自己的感觉,
    当在键盘中输入“c”时,我会觉得由于有p=&child;这一句代码,我会认为结果都是:
    1 This is child,function1
    2 This is child,function2

    但是结果却是:

    1 This is parent,function1
    2 This is child,function2
    因为虽然实际上这个指针指向的是Child类的对象,但编译器无法知道这一事实,它只能按照调用Parent类的函数来理解并编译,所以我们看到了第一行的结果。
    第二行中调用了子类的function2,完全是因为virtual 的功能,virtual实现了动态联编,它可以在运行时判断指针指向的对象,并自动调用相应的函数。
     p=&parent; //这一句,该指针很明显的是指向父类,那么肯定调用的是父类的方法 
  • 相关阅读:
    Linux内核RPC请求过程
    二分图
    Java实现 蓝桥杯 算法提高 合并石子
    Java实现 蓝桥杯 算法提高 合并石子
    Java实现 蓝桥杯 算法提高 摩尔斯电码
    Java实现 蓝桥杯 算法提高 摩尔斯电码
    Java实现 蓝桥杯 算法提高 文本加密
    Java实现 蓝桥杯 算法提高 文本加密
    Java蓝桥杯 算法提高 九宫格
    Java蓝桥杯 算法提高 九宫格
  • 原文地址:https://www.cnblogs.com/zhiminyu/p/12731939.html
Copyright © 2011-2022 走看看