虚函数理解

目录

什么是虚函数?

虚函数作用

虚函数的工作原理

虚函数实例:

什么函数不能声明为虚函数?


什么是虚函数?

指向基类的指针在操作它的多态对象时,可以根据指向的不同类对象调用其相应的函数,这个函数就是虚函数。

虚函数作用

定义了虚函数后,可以在派生类中对虚函数进行重新定义,并且可以通过基类指针或引用,在程序的运行阶段动态的选择调用基类和不同派生类中的同名函数。(如果在派生类中没有对虚函数重新定义,则它继承其基类的虚函数)

虚函数的工作原理

编译器处理虚函数的方法:给每一个对象添加一个隐藏成员。隐藏成员中保存了一个指向函数地址数组的指针。这种数组称为虚函数表。虚函数表中存储了为类对象进行声明的虚函数地址。例如,基类对象包含一个指针指向基类中所有虚函数的地址表。派生类对象将包含一个指针指向独立地址表,如果派生类提供了虚函数的新定义,该虚函数表将保存新函数的地址,如无将保存函数原始版本的地址。

总之,使用虚函数时,在内存和执行速度方面有一定的成本:

  • 每个对象都将增大,增大量为存储地址的空间;
  • 对于每个类,编译器都创建一个虚函数地址表
  • 对于每个函数调用,都需要执行一项额外的操作,即到表中查找地址。

虚函数实例:

class Base
{
public:
	virtual void Print()
	{
        print("this is class Base!\n");
    }
};

class Derived1 :public Base
{
public:
	void Print()
	{
        print("this is class Derived1!\n");
    }
};

class Derived2 :public Base
{
public:
	void Print()
	{
        print("this is class Derived2!\n");
    }
};

int main()
{
	Base Cbase;
    Derived1 child1;
    Derived2 child2;
    Cbase.Print();
    child1.Print();
    child2.Print();

    cour<<"---------"<<endl;
    Base *p1 = &Cbase;
    Base *p2 = &child1;
    Base *p3 = &child2;

    p1->Print();
    p2->Print();
    p3->Print();
    
}


/*
this is class Base!
this is class Derived1!
this is class Derived2!
--------------
this is class Base!
this is class Derived1!
this is class Derived2!
*/

什么函数不能声明为虚函数?

  • 普通函数(非成员函数)

非成员函数只能被重载overload,不能被覆盖override,声明为虚函数也没有什么意思

  • 静态成员函数

静态成员函数对于每一个类来说只有一份代码,所有的对象都共享这一份代码,没有必要动态绑定

  • 内联成员函数

inline函数在编译时被展开,虚函数在运行时才能动态绑定函数

  • 构造函数

构造函数是为了明确初始化对象成员才产生的,然而virtual function主要是为了再不完全了解细节的情况下也能正确处理对象。另外virtual函数是在不同类型的对象产生不同德动作,前提是有对象。

  • 友元函数

c++不支持友元函数的继承,没有继承特性的函数没有虚函数的说法

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值