美文网首页
c++虚函数

c++虚函数

作者: 狗尾巴草败了 | 来源:发表于2017-08-13 15:34 被阅读0次

    说到虚函数,首先要讲一下OOP中的多态多态简单的说就是一个接口,多种实现.

    多态分为编译时多态运行时多态
    编译时多态主要体现在函数重载;
    运行时多态是指程序在运行时动态地识别对象,实现不同的行为,这是通过虚函数+继承实现的。

    虚函数必须是类的非静态成员函数,也不能是构造函数, 访问权限为public, 虽然在语法上设置成 privateprotect 并没有错误,但虚函数的目的是为了实现多态,所以设置成 protectprivate 是没有意义的。

    静态成员函数不能是 virtual 函数的原因

    • 静态成员函数可以不通过对象来调用,静态成员函数没有隐藏的this指针;virtual函数只能通过对象来调用,实现需要依靠隐藏的this指针
    • 静态成员函数是在编译时就绑定了,而virtual函数在运行时才进行绑定

    构造函数不能是 virtual 函数的原因

    • 首先从设计理念上来说,构造函数不需要设置成 virtual 函数,从实现机制来说,构造函数也无法实现 virtual 函数
    • 构造函数顾名思义就是构建一个对象,而虚函数是动态的识别对象的类型,这个对象属于是基类、派生类还是更深层次的类,这是运行在对象已经存在的基础上的。所以虚函数的调用必须在构造函数调用之后
    • 虚函数的执行依赖于虚函数指针 vptr, 而 vptr 的初始化即让 vptr 指向 虚函数表 V-table 是在构造函数中实现的,所以
      构造函数不能是虚函数

    虚函数表 vtable 和虚函数表指针 vptr

    C++的虚函数的实现机制依靠的就是 vtablevptr
    vtable 实际上就是 virtual 函数的地址表,这张表解决了继承和覆盖的问题
    例如:

    class A {
    public:
            virtual void f();
            virtual void g();
    };
    class B: public A{
     public:
              virtual void f();
              virtual void h();
    };
    
    B::f() A::g() B::h() 0

    上面表格则为B的 vtable, 最后一个值如果为1说明还有下一个虚函数表,存在于多重继承的情况下。
    B类的内存分布的第一项即是 vptr,该指针指向B的 vtable

    注意:

    vtable 在编译时期确立, vptr 在运行期确立。

    在继承中析构函数一定要被设置成虚函数

    如果不设置成虚函数,那么当父类的指针调用子类的对象,该指针调用析构函数,将会调用父类的析构函数,而子类多出的那一部分数据内存将无法被释放。

    相关文章

      网友评论

          本文标题:c++虚函数

          本文链接:https://www.haomeiwen.com/subject/wnherxtx.html