c++虚函数

说到虚函数,首先要讲一下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++虚函数 C++虚函数是多态性实现的重要方式,当某个虚函数通过指针或者引用调用时,编译器产生的代码直到运行时才...
    小白将阅读 1,756评论 4 19
  • 什么是继承?什么是多重继承?多重继承存在变量和函数名冲突怎么办?子类对象和父类对象的内存模型是什么样的?虚继承如何...
    金戈大王阅读 2,658评论 3 12
  • 参考来源:知乎 定义一个函数为虚函数,不代表函数为不被实现的函数。定义他为虚函数是为了允许用基类的指针来调用子类的...
    夜幕青雨阅读 859评论 0 6
  • 今天是哥哥选择离开这个世界是日子,过去了这么多年,他的真依然留在我们的心中。 对于哥哥的离开,大多数的人都只是关注...
    知更鸟Robin阅读 317评论 0 0
  • 这个世界上好看的脸蛋太多,有趣的灵魂太少。 ——王尔德 今天妈妈发微信图片给我,图片是一株颜值有点低,有点丑但是看...
    爱吃肉的小仙女阅读 709评论 0 2