C++:虚函数

文章介绍了C++中的面向对象特性,特别是虚函数的实现方式,通过虚函数表和虚指针。每个类都有自己的虚表,对象的首地址指向这个表。析构函数被定义为虚函数是为了确保正确地销毁派生类的对象,防止内存泄漏。构造函数和成员函数模板不能是虚函数,因为它们在不同的时间点和条件下无法正确指向虚表。
摘要由CSDN通过智能技术生成

C++面向对象的三个特性,封装继承多态。在继承的关系中,所有的东西都可以被继承下来,如数据可以被继承下来在内存,而函数的继承则是继承调用权。

虚函数主要是通过虚函数表来实现。一个空类的sizeof大小是多少呢?是1,如果往里面添加两个成员函数呢?sizeof大小还是1,因为成员函数不占用类的内存空间,但是如果增加一个虚函数呢?sizeof大小为4。这是因为类中有一个虚函数,就会创建一个虚函数指针,这个指针指向的就是虚函数表。然后sizeof多出来的大小就是这个虚函数指针的大小。

每个类都有自己的虚表,当你创建一个对象时候,对象的首地址处存放指向虚表的指针。下图是虚表的概念,其实不难。当子类继承父类的时候,会继承父类的虚函数表,这个时候如果在子类中重写父类中的虚函数,那么虚函数表中指向的函数地址也会发生改变,如果没有发生重写,则会指向原来的地址,以这种方式实现运行时候多态。

如果希望禁止子类重写虚函数,则需要声明final虚函数,被声明为 final 的类不能用作基类。

下面是以问题的方式来进行虚函数相关的学习。

1、虚函数如何实现的?会变慢吗?

虚函数是通过虚函数表实现的,每个类都有自己的虚表,对象的首地址处存放有指向虚表的指针。当具体调用哪个虚函数可以在编译期间确定的时候,虚函数不一定更慢。

2、构造函数、析构函数、重载运算符函数可以是虚函数吗?类成员函数模板可以是虚函数吗?

析构函数和重载运算符函数都可以是虚函数,但是构造函数不能是虚函数,因为构造函数是用来创建对象的,在创建对象期间,存放虚函数地址的虚表还没有创建完成,如果直接调用虚函数会引发异常。类成员函数模板不能是虚函数,因为C++在链接前是不知道成员函数模板被实例化多少次的,这就会导致编译器无法在编译期间确定虚表的大小。

3、为什么把析构函数定义为虚函数

如果释放父类指针指向子类对象的时候,析构函数不设置为虚函数就会只析构基类而不析构子类。会造成内存泄露。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值