精华内容
下载资源
问答
  • 2022-04-17 20:37:46

    成为虚函数的前提/要求

    1. 虚函数将来是要被存放在虚函数表中的,所以函数能被取地址l;
    2. 而虚函数表是存放在对象的前四个字节(一般),所以函数的需要调用依赖对象,取出对象的虚函数表的地址。

    常见函数鉴别:

    • 构造函数:不可以,此时对象不存在(构造函数中调用的任何函数都是静态绑定)
    • 析构函数:可以,解决堆上对象派生类部分的资源泄露问题
    • 静态成员方法:不可以,静态方法调用不依赖对象
    更多相关内容
  • 当一个函数是内联和虚函数时,会发生代码替换或使用虚表调用吗? 为了弄清楚内联和虚函数,让我们将它们分开来考虑。通常,一个内联函数是被展开的。 class CFoo { private:  int val; public:  int GetVal...
  • 拥有 Virtual 关键字的函数称之为虚函数 虚函数的作用是实现动态绑定的,也就是说程序在运行的时候动态的的选择合适的成员函数 那么,有哪些函数可以成为虚函数?那些函数不可以成为虚函数? 要成为虚函数必须...

    一,什么是虚函数

    拥有 Virtual 关键字的函数称之为虚函数

    虚函数的作用是实现动态绑定的,也就是说程序在运行的时候动态的的选择合适的成员函数

    那么,有哪些函数可以成为虚函数?那些函数不可以成为虚函数?

    要成为虚函数必须满足两点,一就是这个函数依赖于对象调用,因为虚函数就是依赖于对象调用,因为虚函数是存在于虚函数表中,有一个虚函数指针指向这个虚表,所以要调用虚函数,必须通过虚函数指针,而虚函数指针是存在于对象中的。二就是这个函数必须可以取地址,因为我们的虚函数表中存放的是虚函数函数入口地址,如果函数不能寻址,就不能成为虚函数。

     

    二,哪些函数不能成为虚函数?

    1.内联函数:我们都知道内联函数只是在函数调用点将其展开,它不能产生函数符号,所以不能往虚表中存放,自然就不能成为虚函数。

    2.静态函数:定义为静态函数的函数,这个函数只和类有关系,它不完全依赖于对象调用,所以也不能成为虚函数。

    3.构造函数:都知道只有当调用了构造函数,这个对象才能产生,如果把构造函数写成虚函数,这时候我们的对象就没有办法生    成。更别说用对象去调用了。所以构造函数不能成为虚函数。

    4.友元函数:友元函数不属于类的成员函数,不能被继承。对于没有继承特性的函数没有虚函数的说法。

    5.普通函数:普通函数不属于成员函数,是不能被继承的。普通函数只能被重载,不能被重写,因此声明为虚函数没有意义。因为编译器会在编译时绑定函数。

     

    三,哪些函数可以成为虚函数呢?

    1.普通的成员方法是可以成为虚函数的

    2.还有析构函数,因为析构函数是为了释放对象的,所以之前我们的对象已经生成,而且析构函数可以取地址,所以可以成为虚函数。

     

    四,什么情况下,析构函数必须定义为虚函数。

    当我们定义了一个基类指针,然后在堆上new了一个派生类的对象,让这个指针指向堆上开辟的这块内存。

    Base *p = new Derive(10);
    delete p;

    如果基类的析构函数没有写成虚函数,delete这个基类指针,就不能释放掉堆上的派生类对象。因为delete p会调用基类的析构,你觉得调用基类的析构函数会释放掉派生类的对象吗?当然是不可能的。所以我们就要把基类的析构函数写成虚函数。写成虚函数后,当delete的时候,先会去基类调用析构函数,一看基类的析构函数是虚函数,就会自动的到派生类中调用派生类的析构函数。这时候派生类的对象就能释放了。
     

    展开全文
  • 虚函数表就是存放虚函数地址的一个指针数组,虚函数指针就是指向虚函数表的一个指针。 同一个类的不同实例共用同一份虚函数表,他们都通过一个虚表指针指向该虚函数表。虚函数表是在编译期间创建好的,只存在一份。...

    面向对象语言C++三大特性之一——多态,分为静态多态和动态多态。

    静态多态指重载,在编译期间就已经绑定,确定调用的函数。

    动态多态就是编译时不确定将要调用的函数,因为虚函数的存在,子类重写父类的虚函数,只有运行时才能确定。

    正因为有虚函数的存在,才能实现动态多态。

    虚函数表就是存放虚函数地址的一个指针数组,虚函数指针就是指向虚函数表的一个指针。

    同一个类的不同实例共用同一份虚函数表,他们都通过一个虚表指针指向该虚函数表。虚函数表是在编译期间创建好的,只存在一份。实例化类对象时,编译器自动将类对象的虚表指针指向虚函数表。

    虚表指针是在调用构造函数时获得值的,所以构造函数一定不能是虚函数。(因为调用虚函数需要虚表指针获得地址,若构造函数是虚函数,此时虚表指针还没有赋值,无法调用)

    子类继承父类,也会同时将父类的虚函数表继承,若子类重写虚函数,则虚函数表中该虚函数指向的地址会被替换为子类重写的虚函数地址。若子类定义自己的虚函数,则在原始的虚函数表中后面会添加指向该虚函数的地址。

    建议详细阅读下面的参考内容,通俗易懂,相信你会有收获。

    参考:https://blog.twofei.com/496/

    展开全文
  • 什么函数不能声明为虚函数

    千次阅读 2019-04-30 09:19:34
    一、首先回顾下什么是虚函数及其作用,以便更好理解什么函数不能声明或定义为虚函数: 1. 定义: 虚函数必须是基类的非静态成员函数,其访问权限可以是protected或public,在基类的类定义中定义虚函数的一般形式:...

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

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

     

    展开全文
  • 经检验下面的几个函数都不能定义为虚函数: 1)友元函数,它不是类的成员函数 2)全局函数 3)静态成员函数,它没有this指针 4)构造函数,拷贝构造函数, 赋值运算符重载可以(但是一般不建议作为虚函数) ...
  • 哪些函数不能声明为虚函数
  • 1.为什么C++不支持普通函数为虚函数? 普通函数(非成员函数)只能被overload,不能被override,声明为虚函数也没有什么意思,因此编译器会在编译时邦定函数。 2.为什么C++不支持构造函数为虚函数? 2.1含有虚函数...
  • C++中的虚函数的作用主要是实现了多态的机制,关于多态,简而言之就是用父类型别的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数。...可以设置为虚函数的:  析构函数 普通的成员函数...
  • 什么函数不能被声明为虚函数? 1、普通函数(非类成员函数); 2、构造函数; 3、内联函数; 4、静态成员函数; 5、友元函数; 6、不会被继承的基类的析构函数(没有必要)。 1、普通函数(非类成员函数)不能被声明...
  • 小米二面 在牛客网上的C++面筋题。 1. 虚函数和纯虚函数的区别 因为写代码时不能在一开始就确定被调用的是基类的函数,还是哪个派生类的成员函数,所以C++...定义一个函数为虚函数,不代表函数为不被实现的函数。定
  • 2013级,C++程序设计课件。第12章 多态性与虚函数,内容 12.1 多态性的概念 12.2 一个典型的例子 12.3 虚函数 12.4 纯虚函数与抽象类 课程主页在:http://blog.csdn.net/sxhelijian/article/details/11890759
  • 析构函数可以是虚析构函数。因为可以用基类指针或者引用指向派生类型,如果基类的析构函数不是虚函数,那么只会调用指针类型的析构函数,导致内存泄漏 ...
  • 不能为虚函数的有:(1)构造函数,(2)静态函数,(3)内联函数,(4)友元函数 理解角度: (1)因为多态是动态联编的。 (2)从编译器的角度去理解,你的境界就不一样了 构造函数,因为从语义上不支持,本来是为了...
  • C++笔记——虚函数与动态联编 动态联编?静态联编? 程序调用函数时,将使用哪个可执行代码块呢?编译器负责回答这个问题。将源代码中的函数调用解释执行特定的函数代码块被称为函数名联编(binding)。在C语言中...
  • 只指定了平均睡觉八小时(虚函数),其中没有指定具体的吃饭,叫唤的行为。(纯虚函数) 然后细分一下,动物有猫狗羊和人。(继承) 人类明确它们物种的时候(明确类型的派生类指针) 猫吃鱼 狗吃肉 羊吃草 猫喵喵 狗汪汪 ...
  • C++ 多态意味着调用成员函数时,会根据调用函数的对象的类型来执行不同的函数。下面的实例中,基类 Shape 被派生两个类,如下所示:#include using namespace std;class Shape {protected:int width, height;...
  • 非成员函数(只能重载)、构造函数(虚函数需要使用对象调用)、静态成员函数(属于类)、内联成员函数、友元函数这五种,下面分别解释什么这五种函数不能被声明成虚函数。 1. 非成员函数  非成员函数只能被...
  • 在计算机科学中,内联函数(有时称作在线函数或编译时期展开函数)是一种编程语言结构,用来建议编译器对一些特殊函数进行内联扩展(有时称作在线扩展);也就是说建议编译器将指定的函数体插入并取代每一处调用该...
  • 本篇文章由zg51747708曾广 原创,未经允许不可以转载 ...于是写下这篇博客,来帮助大家更深入的理解虚函数,纯虚函数,虚函数表。希望大家带着批判来阅读,如有错误请私聊我,谢谢! 一.虚函数与纯虚函数定义的解释
  • 虚函数实现多态

    2019-09-05 15:56:48
    基类指针可以指向子类对象,假设基类中的函数并没有定义成虚函数,那么这个指针就无法调用子类的函数,思维习惯上,如果指针指向了子类对象就应该调用子类的成员函数,但是如果不声明该函数为虚函数,就无法访问子类...
  • 子类必须重载父类里的虚函数 子类必须重载父类里的纯虚函数 虚基类的构造函数在非虚基类之前调用(最终继承类构造函数中,成员初始化列表同时出现对虚基类和非虚基类构造函数的调用时,虚基类的构造函数先于非虚基类...
  • 动态联编是以虚函数为基础 B.动态联编是运行时确定所调用的函数代码的 C.动态联编调用函数操作是指向对象的指针或对象引用 D.动态联编是在编译时确定操作函数的 3、在派生类中重新定义虚函数时必须在(A,B,E...
  • 初识虚函数 用virtual关键字说明的函数; 虚函数是实现运行时多态性基础; C++中的虚函数是动态绑定的函数; 虚函数必须是非静态的成员函数,虚函数经过派生之后,就可以实现运行过程中的多态; 一般成员函数可以...
  • 3.构造函数可以声明为虚函数。(F) 4.构造函数可以声明纯虚函数。(F) 5.虚函数不能是类的静态成员。(T) 6.重定义虚函数的派生类必须是公有继承的。(T) 7.作为虚函数隐含参数的this指针,决定了虚函数调用时...
  • 复变函数 —— 4. 什么是调和函数

    千次阅读 2021-12-11 21:19:40
    调和函数的定义例1.例2. 1. 调和函数的定义 在《浅谈矢量场 —— 1. 梯度、散度与拉普拉斯算子》 这篇文章中提到过「拉普拉斯算子」,它的表达形式一般如下: Δ=∇2=∂2∂x2+∂2∂y2+∂2∂z2 \Delta = \nabla^2 = ...
  • Python中,下列( )内置函数可用于读取从键盘上输入的数据更多相关问题加强了与十二经脉的联系并调节十二经脉气血的是A.别络B.经别C.浮络D.正经E.奇经下列药物的配伍属于"十九畏"的是A、川乌与半夏B、硫磺与芒硝C、...
  • 简单来说虚函数(Virtual)已经包含了也必须包含默认的实现,所以在派生类中可以重新实现也可以不实现这些虚函数。 抽象函数(abstract)没有提供默认实现,所以在派生类中必须实现这些抽象函数。 接口中的函数...
  • 我们知道,要想重写基类的虚函数,函数名称、参数、返回类型必须相同,才能够实现多态。 class a { public: a() = default; virtual void display(int a)const { std::cout << " A virtual" << ...
  • 三角形类(triangle)、圆类(circles),利用用虚函数给出具体的求面积函数,并求它们的 和。要求用基类指针数组,使它的每一个元素指向一个派生类。 个人答案: #include <iostream> using namespace std; ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 19,826
精华内容 7,930
关键字:

下列函数为虚函数的是