虚函数与多态(一)

来源:互联网 发布:php 判断是否是移动端 编辑:程序博客网 时间:2024/06/15 07:37

1.多态

   (1)多态性是面向对象程序设计的重要特征之一。

   (2)多态性是指发出相同的消息被不同类型的对象接收时,有可能导致完全不同的行为。

   (3)多太的实现:函数重载,运算符重载,模板,虚函数

2.静态绑定与动态绑定

   (1)静态绑定:绑定过程出现在编译阶段,在编译期就已确定要调用的函数。

   (2)动态绑定:绑定过程工作在程序运行时执行,在程序运行时才确定将要调用的函数。

3.虚函数

   (1)虚函数的概念:在基类中冠以关键字virtual的成员函数

   (2)虚函数的定义:

             [1]virtual 函数类型 函数名称(参数列表)

             [2]如果一个函数在基类中被声明为虚函数,则它在所有派生类中都是虚函数

   (3)只有通过基类指针或引用调用虚函数才能引发动态绑定

   (4)虚函数不能声明为静态

4.虚析构函数

   (1)何时需要虚析构函数?

   (2)当你可能通过基类指针删除派生类对象是

   (3)如果你算允许其他人通过基类指针调用对象的析构函数(通过delete这样做是正常的),并且被析构的对象是有重要的析构函数的派生类的对象,就需要让基类的析构函数作为虚函数

5.虚表指针

   (1)虚函数的动态绑定是通过虚表来实现的

   (2)包含虚函数的类头4个字节存放指向虚表的指针


#include <iostream>using namespace std;class Base {public:virtual void Fun1() {cout << "Base::Fun1" << endl;}virtual void Fun2() {cout << "Base::Fun2" << endl;}int data1_;};class Derived : public Base {public:virtual void Fun2() override final {cout << "Derived::Fun2" << endl;}virtual void Fun3() {cout << "Derived::Fun3" << endl;}int data2_;};typedef void (*FUNC)();int main() {cout << sizeof(Base) << endl;cout << sizeof(Derived) << endl;Base b;long**p = (long**)&b;FUNC fun = (FUNC)p[0][0];(*fun)();fun = (FUNC)p[0][1];(*fun)();cout << endl;Derived d;p = (long**)&d;fun = (FUNC)p[0][0];(*fun)();fun = (FUNC)p[0][1];(*fun)();fun = (FUNC)p[0][2];(*fun)();cout << endl;Base* pp = &d;pp->Fun2();  // 动态绑定d.Fun2();  //  静态绑定 return 0;}

6.object slicing与虚函数

模板方法模式

#include <iostream>using namespace std;class CObject {public:virtual void Serialize() {cout << "CObject::Serialize ..." << endl;}};class CDocument : public CObject {public:int data1_;CDocument() {cout << "CDocument()" << endl;}CDocument(const CDocument& other) {cout << "CDocument(const CDocument& other)" << endl;}void func() {cout << "CDocument::func ..." << endl;Serialize();}virtual void Serialize() override {cout << "CDocument::Serialize ..." << endl;}};class CMyDoc : public CDocument {public:int data2_;virtual void Serialize() override {cout << "CMyDoc::Serialize ..." << endl;}};int main() {CMyDoc mydoc;CMyDoc* pmydoc = new CMyDoc;cout << "#1 testing" << endl;mydoc.func();cout << "#2 testing" << endl;((CDocument*)(&mydoc))->func();cout << "#3 testing" << endl;pmydoc->func();cout << "#4 testing" << endl;((CDocument)mydoc).func();  // mydoc对象强制转换为CDocument对象,向上转型   //完完全全将对象转化为基类对象   //调用默认的拷贝构造函数delete pmydoc;pmydoc = NULL;return 0;}

7.overload,override,overwrite 

 (1)成员函数被重载的特征:overload

             [1]相同的范围(在同一个类中);

             [2]函数名字相同;

             [3]参数不同;

             [4]virtual关键字可有可无

  (2)覆盖是指派生类函数覆盖基类函数,特征是:override

            [1]不同的外围(分别位于派生类与基类);

            [2]函数名字相同;

            [3]参数相同;

            [4]基类函数必须有virtual关键字

   (3)重定义(派生类与基类):overwrite

            [1]不同的范围(分别位于派生类与基类);

            [2]函数名与参数都相同,无virtual关键字;

            [3]函数名相同,参数不同,virtual可有可无

阅读全文
1 0
原创粉丝点击