虚函数 inline函数

虚函数 inline函数一、首先回顾下什么是虚函数及其作用,以便更好理解什么函数不能声明或定义为虚函数:1.定义:虚函数必须是基类的非静态成员函数,其访问权限可以是protected或public,在基类的类定义中定义虚函数的一般形式:  virtual函数返回值类型虚函数名(形参表)  {函数体}2.作用:虚函数的作用是实现动态联编,也就是在程序的运行阶段动态地选择合

大家好,又见面了,我是你们的朋友全栈君。

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

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的"

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/160383.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • drupal linux安装,在Debian 10(Buster) Linux服务器中安装drupal 8.8.0的说明

    drupal linux安装,在Debian 10(Buster) Linux服务器中安装drupal 8.8.0的说明按照本说明,你就可以成功的在Debian10(Buster)Linux服务器中安装好drupal8.8.0版本,已亲测能稳定运行。先决条件在开始安装之前,对安装的最低要求是:数据库服务器,如MySQL、MariaDB、PostgreSQL、Percona、SQLite等。Web服务器,如Nginx、Apache。PHP7.x,推荐>=7.2。至少1GB的磁盘空间。同时,要更新你的De…

    2022年7月20日
    16
  • resque 遍历加载job目录下的类

    resque 遍历加载job目录下的类

    2022年2月21日
    42
  • ostaskcreate函数作用_认识上中下

    ostaskcreate函数作用_认识上中下OSTaskCreate()是学习ucos-Ⅱ操作系统的第一个函数,费了九牛二虎之力,现在感觉差不多可以过了。#ifOS_TASK_CREATE_EN>0INT8UOSTaskCreate(void(*task)(void*p_arg),void*p_arg,OS_STK*ptos,INT8Uprio)/*1*/{ OS_STK…

    2025年9月17日
    4
  • jboss 下载_JbusDriver

    jboss 下载_JbusDriver如下地址栏里有JBOSS的所有版本的下载文件:http://sourceforge.net/projects/jboss/files/JBoss/ 大家只需到里面下载自己所需的就可以了 在本文中,我JBoss下载的版本为:JBOSS5.0Beta4。下载地址:http://www.jboss.org/jbossas/downloads/

    2022年10月4日
    3
  • can’t connect to MySQL server on_mysql安装1045错误代码

    can’t connect to MySQL server on_mysql安装1045错误代码当您创建具有’%’的用户时,如果您使用localhost删除用户,则会发生此错误。让我们用“%”创建一个用户,并将该用户删除为本地主机。语法如下CREATEUSER’yourUserName’@’%’IDENTIFIEDBY’yourPassword’;让我们使用以上语法创建一个用户。创建用户的查询如下mysql>CREATEUSER’Jack’@’%’IDENTIFIED…

    2022年8月12日
    4
  • session.setattribute 方法_session如何设置和读取

    session.setattribute 方法_session如何设置和读取session.setAttribute()和session.getAttribute()的用法: session.setAttribute(“sessionName”,Object);//保存 //用来设置session值的,sessionName是名称,object是你要保存的对象。 session.getAttribute(“sessionName”);//取得 //用来得到对应名称的session值,即得到object对象,注意需要进行类型转换!…

    2022年8月31日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号