虚函数 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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • (OS 10038)在一个非套接字上尝试了一个操作 的解决办法[通俗易懂]

    在SVN的机器上,系统盘,剩余空间不足1G,经查看,是C:\ProgramFiles(x86)\ApacheSoftwareFoundation\Apache2.2\logs里面存在了很多(每天一个)很大(600M或6G的)日志文件,error-2015-07-31.logs删除后,不几天就会重新生成。打开error-2015-07-31.logs文件,发现,如下信息【(OS10

    2022年4月13日
    77
  • outputstreamwriter.write_writevalueasstring

    outputstreamwriter.write_writevalueasstring一.输出流1.1字节输出流OutputStream在java中,字节是占1个字节,即8位字节输出流OutputStream-将指定的字节写入此输出流1.2字符流Writer在java中,字符是占2个Byte,即16位字符输出流Writer-将字符写入此输出流,字符流的操作比字节流操作好在一点,比如可以直接输出字符串1.3OutputStreamWri

    2025年10月28日
    3
  • Nginx的启动(start),停止(stop)命令

    Nginx的启动(start),停止(stop)命令

    2021年10月14日
    137
  • 操作系统实验一进程管理与进程通信(计算机进程)

    1.实验目的学习如何利用管道机制、共享存储区机制进行进程间的通信,并加深对上述通信机制的理解。2.实验内容(1)了解系统调用pipe()、shmget()、shmat()、shmdt()、shmctl()的功能和实现过程。(2)编写一段程序,使其用管道来实现父子进程之间的进程通信。子进程向父进程发送自己的进程标识符,以及字符串“issendingamessageto…

    2022年4月12日
    136
  • 微服务架构-实现技术之具体实现工具与框架5:Spring Cloud Feign与Ribbon原理与注意事项

    微服务架构-实现技术之具体实现工具与框架5:Spring Cloud Feign与Ribbon原理与注意事项目录一、SpringCloudFeign概述与工作原理解读(一)服务间调用的几种方式(二)Feign概述二、FeignClent注解剖析+SpringCloudFeign基本功能配置解读(一)@FeignClient注解剖析(二)SpringCloudFeign基本功能配置(三)Feign请求超时问题方法一方法二方法三三、SpringC…

    2022年4月29日
    52
  • 矩阵范数与矩阵的模

    矩阵范数与矩阵的模我的机器学习教程「美团」算法工程师带你入门机器学习已经开始更新了,欢迎大家订阅~任何关于算法、编程、AI行业知识或博客内容的问题,可以随时扫码关注公众号「图灵的猫」,加入”学习小组“,沙雕博主在线答疑~此外,公众号内还有更多AI、算法、编程和大数据知识分享,以及免费的SSR节点和学习资料。其他平台(知乎/B站)也是同名「图灵的猫」,不要迷路哦~矩…

    2022年5月15日
    61

发表回复

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

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