zoukankan      html  css  js  c++  java
  • Return to the Basic 虚函数(virtual)

    虚函数是指在基类中使用了vitual申明,并且在一个或多个派生类中被重新定义的函数。-> 每个派生类可以拥有自己的虚函数定义。
    - C++根据指针指向对象的类型来决定调用虚函数的哪个定义,这种定义实在运行时作出的。
    - 当虚函数在派生类中重新定义时,关键字virtual 不需要重复。(重复也不是错误)
       ;虚函数的继承: 无论经过多少层的继承函数,都是虚函数。
    - 包含虚函数的类被称为多态类。
       ;虚函数+继承,使C++支持运行多态.(Polymorphism)

    #include <iostream>
    using namespace std;
    
    class base{
    
    public:
     virtual void who(){   //申明虚函数
      cout<<"Base\n";
     }
    };
    
    class derived1:public base{
    
    public:
     void who(){    //重新定义 derived1 中的who()
      cout<<"derived1 class\n";
     }
    };
    
    class derived2:public base{
    
    public:
     void who(){    //重新定义 derived2 中的who()
      cout<<"derived2 class\n";
     }
    };
    
    int main(){
     base base_obj;
     base *p;
     derived1 derived1_obj;
     derived2 derived2_obj;
    
     p=&base_obj;
     p->who();
    
     p=&derived1_obj;
     p->who();
    
     p=&derived2_obj;
     p->who();
    
     return 0;
    }
    
    


    输出结果:
    Base
    derived1 class
    derived2 class

    如果在上述代码中删除virtual,将输出
    Base
    Base
    Base

    在类base中, 函数who()被申明为虚函数,说明该函数可以在派生类中重新定义。
    因此,derived1,derived2中的 who()都重新被定义了。

    由于who()被声明为虚函数,在运行时,C++根据p所指向的对象类型决定who()的那个定义将被调用.
    同时,由于基类的指针可以指向任何派生类的对象。

    重载(Overloading)一般的函数和重新定义虚函数(Overriding,覆盖/重写)是有差异的.
    Overloading is a method that allows defining multiple member functions with the same name but different signatures.The compiler will pick the correct function based on the signature.
    Overriding is a method that allows the derived class to redefine the behavior of member functions which the derived class inherits from the base class.The signatures of both base class member function and derived class member function are the same; however, the implementation and behavior will differ.
    - 重载函数必须在参数的类型和数量上不同,覆盖函数(重新定义虚函数)在参数的类型而后数量上必须相同。


    为了理解多态(一种接口,多种方法)的强大内涵,参考如下代码.

    #include <iostream>
    using namespace std;
    
    //基类figure:保存图形的尺寸,并且可以用于计算其面积show_area().
    class figure{
    protected:
     double x,y; 
    public:
     void set_dim(double i,double j){
      x=i;
      y=j;
     }
     virtual void show_area(){   //采用虚函数,可以在派生类中覆盖(Overloading)面积计算.
      cout<<"No area computation defined for this class.\n";
     }
    };
    
    class triangle:public figure{
    
    public:
     void show_area(){
      cout<<"Triangle with base "<<x;
      cout<<" and height "<<y;
      cout<<" has an area of "<<x*y*0.5<<".\n";
     }
    };
    
    class rectangle:public figure{
    
    public:
     void show_area(){
      cout<<"Rectangle with dimensions ";
      cout<<x<<","<<y;
      cout<<" has an area of ";
      cout<<x*y<<".\n";
     }
    };
    
    int main(){
     figure *p;    //声明基类的指针
     triangle tri_obj;   //声明派生类对象
     rectangle rect_obj;
    
     p=&tri_obj;
     p->set_dim(6.0,8.0);
     p->show_area();   //将显示三角形面积 24
    
     p=&rect_obj;
     p->set_dim(10.0,3.0);
     p->show_area();   //将显示长方形面积 30
    
     return 0;
    }
  • 相关阅读:
    [论文笔记]CVPR2017_Joint Detection and Identification Feature Learning for Person Search
    [论文笔记]Objects as Points
    [论文笔记]ICCV2017_SVDNet for Pedestrian Retrieval
    [论文笔记]ICPR2016_Person Re-Identification Using CNN Features Learned from Combination of Attributes
    VMware ESXI6.0服务器安装系列:RAID设置
    LVM基础详细说明及动态扩容lvm逻辑卷的操作记录
    调用对象 “ha-datastoresystem”的“HostDatastoreSystem.QueryVmfsDatastoreCreateOptions” 失败。
    动态扩容lvm逻辑卷的操作记录
    Kubernetes之Flannel介绍
    Linux服务器同步网络时间
  • 原文地址:https://www.cnblogs.com/fdyang/p/2858746.html
Copyright © 2011-2022 走看看