虚函数默认参数选择

来源:互联网 发布:js单选框点击事件 编辑:程序博客网 时间:2024/05/02 06:12
#include <iostream>class Base {public:virtual void f(int a = 1){std::cout << "Base:: " << a << std::endl;}};class Derived: public Base {public:virtual void f(int a = 2){std::cout << "Derived:: " << a << std::endl;}};int main(){Base *basep = new Derived;basep->f();system("pause");return 0;}


输出结果:

Derived::1

分析:

        默认实参在编译时确定,而函数调用在运行时确定;调用基类版本的virtual函数,会使用基类的默认实参;

        如果是

Derived *basep = new Derived;basep->f();

则输出结果为:

        Derived::2


C++迟绑定实现机理(编译器都是类似于此种方式实现的):
1、为每个含有虚函数的类(基类以及派生类)都创建一张虚函数表(VTable,存储于常量区),依次存放虚函数的地址。对于派生类来说,如果没有重写其基类的虚函数,那么,将会在VTable中存放基类的虚函数地址。
2、为每个含有虚函数的类的对象,创建一个指针(VPtr),指向这个类的虚函数表(所以说,同类对象的
VPtr的值是一样的,也就是说,虚函数,在这一点上,类似于类的static函数,是所有对象共有的。)
3、通过强制转换将派生类对象的地址/引用 赋给基类指针/变量(也就是向上类型转换UpCasting)

4、然后,通过基类指针/引用对象 来调用虚函数(即:polymorphic call),就会通过此时基类对象的VPtr指针在所指向虚函数表中寻址(一般是从表头地址开始,加上一定的偏移量)找到相应的函数地址,也就是之前派生类VPtr指针指向的虚函数表的函数地址。

 

原创粉丝点击