C++继承与多态

来源:互联网 发布:艾米莉狄金森 知乎 编辑:程序博客网 时间:2024/05/16 14:46
简单地说,那些被virtual关键字修饰的成员函数,就是虚函数。虚函数的作用,用专业术语来解释就是实现多态性(Polymorphism),多态性是将接口与实现进行分离;用形象的语言来解释就是实现以共同的方法,但因个体差异,而采用不同的策略。

先来看一个例子。
class Base{public:Base(int a):ma(a){cout<<"Base()"<show();    // call Base::show   静态绑定=>编译时期的绑定/*mov ecx, dword ptr[pb]mov eax, dword ptr[ecx]call eax     动态绑定=》运行时的绑定*/// 函数调用的汇编cout<

用对象直接调用虚函数,是静态绑定,与普通函数相同。
指针(引用)调用虚函数,是动态绑定,指向的对象调用。
在编译阶段,有虚函数会生成虚函数表,存于数据段,并且一个类型生成一个虚函数表。


                                                                                                 虚函数表

定义一个空类,里面没有任何成员变量和成员函数,对该类求sizeof,得到的结果是多少呢?
      答案是1,空类型的实例中不包含任何信息,本来求sizeof为0,但是当我们声明该类型的实例的时候,它必须在内存中占有一定空间。
如果在该类型中添加一个虚函数呢?
     C++编译器一旦发现一个类型中有一个虚函数,就会该类型生成虚函数表,并在该类型的每一个实例中添加一个指向虚函数表的指针所以sizeof为4。

能被声明为虚函数的两个必要条件:
    必须有函数符号产生       //才能将函数地址存入虚函数表中
    必须已经有对象或者依赖对象     // 对象才会有虚函数指针,才能找到虚函数表
内联函数不能作为虚函数,不产生函数符号
静态方法不能作为虚函数,没有this指针,不依赖对象
构造函数不能作为虚函数,此时对象还没有生成。

虚函数编译时期确定函数名,并且压参数。
class A{    public:        virtual void Fun(int number = 10)        {              std::cout<<"A::with number "<<number;        }};class B :public A{    virtual void Fun(int number = 20)    {        std::cout<<"B::with number "<<number;    }};int main(){    B b;    A &a = b;    b.Fun();    a.Fun();    return 0;}
此程序片段输出为:B::witn number 20B::with number 10