• 什么函数不能是虚函数?为什么析构必须是虚函数?


    虚函数

    虚函数:被virtual修饰的基类成员函数。

    纯虚函数

    • 例如virtual void foo() = 0。纯虚函数所在类称为**“抽象类”**,抽象类不能实例化出对象,它的子类必须重写纯虚函数,否则依然是抽象类。
    • 纯虚函数可以有函数体,但是没有意义。

    注:只在子类中声明virtual,无法构成虚函数。

    不能声明为虚函数的函数

    1、普通函数
    普通函数不属于类。

    2、构造函数
    虚函数是为了依据不同的对象来产生不同的状态,但是前提是得有这个对象,而对象的产生必须依靠构造函数;其次,虚函数表指针的初始化也在构造函数的初始化列表阶段,二者矛盾了。

    3、内联成员函数
    内联函数是在编译期间直接在调用位置展开代码,而虚函数是在运行时通过不同对象来判断函数的调用;其次,内联函数没有地址,不能形成虚表。

    4、静态成员函数
    static成员函数是类的所有对象共享的,而虚函数是针对不同对象构成多态,二者矛盾;其次,静态成员函数没有this指针,无法访问虚函数表。

    5、友元函数
    友元函数不属于类的成员函数,不能被继承,更不能声明为虚函数。

    协变

    虚函数重写必须满足:返回值类型、函数名、参数列表都相同,但是协变和析构函数是例外。

    如果基类的虚函数返回的是一个基类的指针或引用,派生类的虚函数返回的是一个派生类的指针或引用,那么这两个函数尽管返回值类型不同,但是依然构成虚函数,这种称为协变

    而虚构函数会被编译器统一命名为destructor,因此满足虚函数的条件。

    构造函数/析构函数内部可以调用虚函数实现多态吗

    语法上支持,但是会失去多态的效果,因为:

    • 构造子类先调用父类的构造函数,相当于父类构造时子类还完全不存在,没有虚函数表指针也就无法构成多态。
    • 析构子类则先调用子类的析构函数,然后调用父类的。那么当父类析构时子类依旧不存在,所以无法构成多态。

    为什么有的析构函数必须设置成虚函数

    如果基类的析构函数是用virtual修饰的虚函数,那么无论派生类的析构函数是否有virtual修饰,它都是虚函数。原因是:

    1. 只要基类虚函数有virtual修饰,那么派生类的virtual可以省略。
    2. 析构函数的名称会被编译器统一处理成destructor,因此它们完全满足名称、参数列表、返回值类型相同的条件。

    在如下情况,第二点格外重要:

    class A{
    public:
    	~A() {}
    };
    class B :public A{
    public:
    	B() { 
    		_a = new int[100]; 
    	}
    	~B() { 
            delete[]_a; 
        }
    private:
    	int* _a;
    };
    int main(){
    	A* p = new B;
    	delete p;
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    如果析构函数不定义成虚函数,那么这里就构成不了多态,我们delete p只会调用p类型的析构函数,即~A(),而B中new的空间就造成了内存泄漏。

  • 相关阅读:
    Python 获取class_name win32gui
    学习pytorch8 土堆说卷积操作
    电力系统机组组合优化调度(IEEE14节点、IEEE30节点、IEEE118节点)(Matlab代码实现)
    域渗透 | kerberos认证及过程中产生的攻击
    linux shell脚本读取并解析yaml文件
    2023最新计算机信息管理毕设选题分享
    冲突域、广播域、一些网络设备
    STM32 CortexM4 主控板触摸屏保姆级别总结
    【微服务】关于WSGI Server即web服务器
    2021年9月电子学会图形化二级编程题解析含答案:帮小企鹅躲避暴风雪
  • 原文地址:https://blog.csdn.net/Wyf_Fj/article/details/126912207