什么函数不能声明为虚函数

    技术2022-05-20  41

    一、首先回顾下什么是虚函数及其作用,以便更好理解什么函数不能声明或定义为虚函数:

    1. 定义:

    虚函数必须是基类的非静态成员函数,其访问权限可以是protected或public,在基类的类定义中定义虚函数的一般形式:

      virtual 函数返回值类型 虚函数名(形参表)  { 函数体 }

    2. 作用:

    虚函数的作用是实现动态联编,也就是在程序的运行阶段动态地选择合适的成员函数,在定义了虚函数后,可以在基类的派生类中对虚函数重新定义,在派生类中重新定义的函数应与虚函数具有相同的形参个数形参类型,以实现统一的接口,不同定义过程。如果在派生类中没有对虚函数重新定义,则它继承其基类的虚函数。

    当程序发现虚函数名前的关键字virtual后,会自动将其作为动态联编处理,即在程序运行时动态地选择合适的成员函数。

    3. 使用方法:

    动态联编规定,只能通过指向类的指针基类对象的引用来调用虚函数,其格式:

      指向基类的指针变量名->虚函数名(实参表)

          基类对象的引用名. 虚函数名(实参表)

    4. 其它说明:  

    虚函数是C++多态的一种表现:

    例如:子类继承了父类的一个函数(方法),而我们把父类的指针指向子类,则必须把父类的该函数(方法)设为virtual(虚函数)。  使用虚函数,我们可以灵活的进行动态绑定,当然是以一定的开销为代价。 如果父类的函数(方法)根本没有必要或者无法实现,完全要依赖子类去实现的话,可以把此函数(方法)设为virtual 函数名=0 我们把这样的函数(方法)称为纯虚函数。  如果一个类包含了纯虚函数,称此类为 抽象类 。

     

    二、什么函数不能声明为虚函数:

    一个类中将所有的成员函数都尽可能地设置为虚函数总是有益的。 设置虚函数须注意: 1:只有类的成员函数才能说明为虚函数; 2:静态成员函数不能是虚函数; 3:内联函数不能为虚函数; 4:构造函数不能是虚函数; 5:析构函数可以是虚函数,而且通常声明为虚函数。

    类里面“定义”的成员函数是内联的,但是仍然可以成为虚函数,那么是不是可以说“内联函数不能成为虚函数”这句话有问题呢,是不是应该改成“显式定义的内联函数不能成为虚函数”。比如下面这个示例程序:  #include   <iostream>  using   namespace   std;  class   Base{          public:          virtual     void   f1(){cout < < "Father " < <endl;}          };  class   Drived1:public   Base{          public:              void   f1(){cout < < "Son1 " < <endl;}          };  class   Drived2:public   Base{          public:              void   f1(){cout < < "Son2 " < <endl;}          };  void   myPrint(Base*   pBs){          pBs-> f1();          }           int   main()  {      Base   father;      Drived1   son1;      Drived2   son2;      myPrint(&father);      myPrint(&son1);      myPrint(&son2);           system( "PAUSE ");     return   0;  }  输出:  Father  Son1  Son2  你可以发现,虽然f1在基类中定义的,按理说应该是内联函数,但是它仍然可以成为虚函  数。 类中定义的成员函数(函数体在类中)能成为虚函数,大部分编译器能够将虽然声明为inline但实际上不能inline的函数自动改为不inline的。至于编译器会不会将inline   and   virtual的函数照模照样的实现,与编译器及优化方式有关。 要想成为虚函数,必须能够被取到地址.内联函数不能被取到地址所以不能成为虚函数.  你写inline   virtual   void   f(),不能保证函数f()一定是内联的,只能保证f()是虚函数(从而保证此函数一定不是内联函数)  对于问题:  到底内联函数能不能成为虚函数?  答案是不能.问题是你不能够确定一个函数到底是不是inline的.inlien关键字只是对编译器的一个建议:"如果有可能,请把此函数搞成inline的"

     


    最新回复(0)