ps:编译器对虚方法使用动态联编,运行时根据对象决定调用父类还是子类的这个方法。
虚函数的工作原理是:基类的对象维护一个虚函数表,所谓的维护,方式是用一个隐藏指针指向虚函数表。这个虚函数表中记录基类中定义的虚函数的函数地址。同样,派生类的对象也维护这样一个虚函数表。不同的是,1)如果派生类并没有重新实现基类的虚方法,则它的虚函数表记录的该函数地址还是维持基类中的不变;2)如果重新实现了,则记录新的函数地址。3)如果派生类还定义了自己的虚函数,则也要加到虚函数表里来。
调用虚函数时候,程序查看虚函数表的地址,然后寻找相应的函数。
所以,使用虚函数有一下成本:
1。会使得对象增大,因为要消耗存储地址的空间。
2。编译器要为每个类都创建虚函数地址表。
3。在表中查找地址需要额外操作。
非虚函数虽然效率高,但不具有动态联编的功能。
使用虚函数要注意:
1。构造函数不能是虚函数
2。析构函数应该是虚函数
3。友元函数不能是虚函数
网友的阐述: 指针的类型是可以强行转来转去的。普通情况你转什么类型就调对应类型的同名函数。但是虚函数实现多态后,尽管可能你把指针转成父类的类型,但是因为创建的时候是子类的类型,它还是会调用子类的这个虚函数。 这样可以统一代码且正确运用子类的新特性。 也因为如此,如果父类虚函数不做实现而=0成为纯虚函数,那么父类就不可以实例化,这个没有实现的虚函数也永远不会调用。因为根据多态的动态联编,总是会调用实例化了的子类的该方法。指针强行转成父类也不会调用纯虚函数。