虚函数简解

虚函数实例

当使用类的指针调用成员函数时,普通函数由指针类型决定,而虚函数由指针指向的实际类型决定。

#include <iostream>
using namespace std;
int main(int argc, char const *argv[])
{
	class base
	{
	public:
		virtual void vir_func(){cout << "virtual function, this is class base" << endl;}
        void func(){cout << "normal function, this is class base" << endl;}
	};
	
	class A:public base
	{
    public:
		virtual void vir_func(){cout << "virtual function, this is class A" << endl;}
        void func(){cout << "normal function, this is class A" << endl;}
	};
	
	class B:public base
	{
    public:
		virtual void vir_func(){cout << "virtual function, this is class B" << endl;}
        void func(){cout << "normal function, this is class B" << endl;}
	};
	
	base *  Base = new(base);base * a = new(A); base * b = new(B);
	Base -> func(); a -> func(); b -> func();

    cout <<"################################" << endl;
    
    Base -> vir_func(); a -> vir_func(); b -> vir_func();
    
    cout <<"################################" << endl;
    
    ((A * )b) -> vir_func(); ((A *)b) -> func();
    
    return 0;
}

输出结果

normal function, this is class base
normal function, this is class base
normal function, this is class base
################################
virtual function, this is class base
virtual function, this is class A
virtual function, this is class B
################################
virtual function, this is class B
normal function, this is class A

在上述例子中,我们首先定义了一个基类base,基类有一个名为vir_func的虚函数,和一个名为func的普通成员函数。而类A,B都是由类base派生的子类,并且都对成员函数进行了重载。然后我们定义三个base类型的指针Base、a、b分别指向类base、A、B。可以看到,当使用这三个指针调用func函数时,调用的都是基类base的函数。而使用这三个指针调用虚函数vir_func时,调用的是指针指向的实际类型的函数。最后,我们将指针b做强制类型转换,转换为A类型指针,然后分别调用func和vir_func函数,发现普通函数调用的是类A的函数,而虚函数调用的是类B的函数。

以上,我们可以得出结论当使用类的指针调用成员函数时,普通函数由指针类型决定,而虚函数由指针指向的实际类型决定。

虚函数的实现过程:通过对象内存中的vptr找到虚函数表vtbl,接着通过vtbl找到对应虚函数的实现区域并进行调用。

虚函数的实现(内存布局)

虚函数表中只存有一个虚函数的指针地址,不存放普通函数或是构造函数的指针地址。只要有虚函数,C++类都会存在这样的一张虚函数表,不管是普通虚函数亦或是纯虚函数,亦或是派生类中隐式声明的这些虚函数都会生成这张虚函数表。

虚函数表创建的时间:在一个类构造的时候,创建这张虚函数表,而这个虚函数表是供整个类所共有的。虚函数表存储在对象最开始的位置。虚函数表其实就是函数指针的地址。函数调用的时候,通过函数指针所指向的函数来调用函数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值