多态章-虚函数-重写-协变-override/final-重写覆盖隐藏的对比-纯虚函数与抽象类-多态的底层-虚函数表-动态绑定-静态绑定
使用的父类子类 基于继承下的虚函数 调用 ——代码复用。形成条件1.必须是基类的指针或引用调用虚函数。2.调用子类中拥有父类的虚函数的重写/覆盖。虚函数类成员函数前加以virtual就成为了虚函数 注意非成员函数无法加virtual修饰。class Student :public Person { public: virtual void Buy() { cout Student Buy endl; } };虚函数的重写/覆盖虚函数的重写与覆盖是通过继承下子类内的同返回类型、同名、同参数类型函数的再次实现。注意即使在子类下重写时不加以virtual只要在父类中有加以virtual的就可以形成重写。协变派生类重写虚函数时与基类的虚函数返回值不同。二者相应的返回值都是自身类的指针或者引用。称这种现象为协变。协变意义不大。协变构成重写。class A {}; class B : public A {}; class Person { public: virtual A* BuyTicket() { cout 买票-全价 endl; return nullptr; } }; class Student : public Person { public: virtual B* BuyTicket() { cout 买票-打折 endl; return nullptr; } };析构函数的重写已了解到析构函数在编译时会将函数名替换为destructor。 //为什么暂时不用管在子类的析构函数中无论是否加以virtual都是父类析构函数的重写一般情况下可以不写。特殊情况class A { public: virtual ~A() { cout ~A() endl; } }; class B : public A { public: ~B() { cout ~B()-delete:_p endl; delete _p; } protected: int* _p new int[10]; }; // 只有派⽣类B的析构函数重写了A的析构函数下⾯的delete对象调⽤析构函数才能 构成多态才能保证p1和p2指向的对象正确的调⽤析构函数。 int main() { A* p1 new A; A* p2 new B; delete p1; delete p2; return 0; }虽然是A类型但是指向的是B类的内容调用A的析构函数后不会调用B的析构函数导致B的内存泄漏。override与final关键字override补全编译器无法检测重写是否构成的的编译问题。在子类的目的重写的虚函数名后加override //类似于constfinal限制类无法进行继承。自然也无重写之说。※重载、重写、隐藏/重定义的对比纯虚函数与抽象类纯虚函数在虚函数的后面加以 0 代表此虚函数为纯虚函数(本就虚还加以0更纯正了)。纯虚函数定不定义均不会调用(重写)。包含纯虚函数的类叫做抽象类——抽象类无法实例化出对象。如果派生类继承抽象类后不重写纯虚函数那么派生类也是抽象类这就一定程度上强迫了派生类必须重写因为不重写无法实例化。多态的底层原理下⾯编译为32位程序的运⾏结果是什么 A. 编译报错 B. 运⾏报错 C. 8 D. 12 class Base { public: virtual void Func1() { cout Func1() endl; } protected: int _b 1; char _ch x; }; int main() { Base b; cout sizeof(b) endl; return 0; }答案D、12 //存在函数指针除了_b与_ch成员还有一个__vfptrvirtual function pointer一个含有虚函数的类中至少都有一个虚函数指针 因为虚函数的地址要能够被这个指针维护。对于Person、student、soldier※虚函数表1.基类对象的虚函数表中存放基类所有虚函数的地址。同类型的对象公用一张虚函数表不同类型的对象有各自独立的虚函数表所以基类和派生类有各自的虚表。2.派生类由两部分构成继承下来的基类和自己的成员。一般情况下继承下来的基类中有虚函数表指针自己就不再生成虚函数表指针。但是要注意的是这里继承下来的基类部分虚函数表指针和基类对象的虚函数表指针不是同一个就像修改派生类中的基类成员不会影响独立的基类对象反之亦然。3.派生类中重写的基类的虚函数-派生类的虚函数表中对应的虚函数就会被覆盖成派生类重写的虚函数地址。4.派生类的虚函数表中包含(不是表的类型)(1)基类的虚函数地址 (2) 重写造成覆盖的虚函数地址 (3) 派生类自己的虚函数地址。动态绑定与静态绑定前言静态绑定Static Binding和动态绑定Dynamic Binding是编程中方法或函数调用的两种不同绑定方式。静态绑定在编译时确定而动态绑定在运行时确定。静态绑定在编译时就可以确定编译器根据声明的变量类型来决定调用哪个方法或函数。动态绑定在运行时才可以确定具体的调用方法由对象的实际类型决定而非变量的声明类型。作业静态成员函数与具体对象无关属于整个类核心关键是静态函数无this指针调用时无法不可以通过类名直接调用无this就代表无法实现虚表。编译时多态是早期绑定主要通过重载实现。模板属于编译时多态。重定义指隐藏A* pa (A*)new B; // pa 的静态类型是 A*实际指向 B 对象 。p-调用B的函数.类有几个拥有虚函数的父类就会有几张虚表自身子类不会产生多余的虚表。virtual关键字只在声明时加上在类外实现时不能加。友元函数本身不是类的成员函数但可以访问类的私有和保护成员。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2539114.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!