二級(jí)C++多態(tài)性:多態(tài)性和虛函數(shù)

字號(hào):

1、 靜態(tài)聯(lián)編和動(dòng)態(tài)聯(lián)編:
    • 聯(lián)編:是指一個(gè)計(jì)算機(jī)程序自身彼此關(guān)聯(lián)的過(guò)程。按聯(lián)編所進(jìn)行的階段不同,可分為兩種不同的聯(lián)編方法。一種是靜態(tài)聯(lián)編,一種是動(dòng)態(tài)聯(lián)編。
    • 靜態(tài)聯(lián)編:聯(lián)編工作出現(xiàn)在編譯連接階段,這種聯(lián)編過(guò)程在程序開始運(yùn)行之前完成。
    例如:一個(gè)靜態(tài)聯(lián)編的例子。
    #include
    class Point
    {
    public:
    Point(double I,double j)
    { x=I;y=j;}
    double Area(){return 0.0;}
    private:
    double x,y;
    };
    class Rectangle :public Point
    {
    public:
    Rectangle(double i,double j,double k,double l);
    Double Area()
    {return w*h;}
    private:
    double w,h;
    };
    Rectangle::Rectangle(double i,double j
    ,double k,double l):point(i,j)
    {
    w=k;h=l;
    }
    void fun(point &s)
    {
    cout<
    }
    void main()
    {
    Rectangle rec(3.0,5.2,15.0,25.0);
    Fun(rec);
    }
    分析程序:在 fun() 函數(shù)中, s 所引用對(duì)象執(zhí)行的 Area() 操作被關(guān)聯(lián)到 point::Area() 的實(shí)現(xiàn)代碼上。這是靜態(tài)聯(lián)編的結(jié)果。在程序編譯階段,對(duì) s 所引用 的對(duì)象所執(zhí)行 的 Area() 操作只能束定到 point 類的函數(shù)上。
    所以執(zhí)行結(jié)果為: 0
    • 動(dòng)態(tài)聯(lián)編:有時(shí)編譯程序在編譯階段,并不能確切知道將要調(diào)用的函數(shù),只有在程序執(zhí)行時(shí)才能確定將要調(diào)用的函數(shù),為此,要確切知道調(diào)用的函數(shù),要求聯(lián)編工作要在程序運(yùn)行時(shí)進(jìn)行,這種在程序運(yùn)行時(shí)進(jìn)行聯(lián)編工作被稱為動(dòng)態(tài)聯(lián)編。
    動(dòng)態(tài)聯(lián)編是在虛函數(shù)的支持下實(shí)現(xiàn)的。
    所以靜態(tài)聯(lián)編和動(dòng)態(tài)聯(lián)編也都屬于多態(tài)性,它們是在不同階段對(duì)不同實(shí)現(xiàn)進(jìn)行的選擇。
    2、 虛函數(shù):(是成員函數(shù),且是非 static 的)
    • 格式: virtual < 類型說(shuō)明符 >< 函數(shù)名 >(< 參數(shù)表 >)
    • 說(shuō)明:①如果某類中的成員函數(shù)被說(shuō)明 為虛函數(shù),就意味著該成員函數(shù)在派生類中可能有不同的實(shí)現(xiàn)。當(dāng)使用這個(gè)成員函數(shù)操作 指針或引用 所標(biāo)識(shí)對(duì)象時(shí),對(duì)該成員函數(shù)調(diào)用采用動(dòng)態(tài)聯(lián)編方式,即在運(yùn)行時(shí)進(jìn)行束定。
    • 態(tài)聯(lián)編只能通過(guò)指針或引用標(biāo)識(shí)對(duì)象來(lái)操作虛函數(shù)。若采用一般類型的標(biāo)識(shí)對(duì)象來(lái)操作虛函數(shù),則采用靜態(tài)聯(lián)編方式調(diào)用虛函數(shù)。
    例如:一個(gè)動(dòng)態(tài)聯(lián)編的例子:
    #include
    class point
    {
    public:
    point(double I,double j)
    {x=I;y=j;}
    virtual double Area()
    {return 0.0;}
    private:
    double x,y;
    };
    class Rectangle:public point
    {
    public:
    Rectangle(double I,double j,double k,double l);
    Virtual double Area()
    {
    return w*h;
    }
    private:
    ouble w,h;
    };
    Rectangle::Rectangle(double I,double j,
    double k,double l):point(I,j)
    {
    w=k;h=l;
    }
    void fun(point &s) // 被動(dòng)態(tài)聯(lián)編
    {
    cout<
    }
    void main()
    {
    Rectangle rec(3.0,5.2,15.0,25.0);
    Fun(rec);
    }
    輸出結(jié)果: 375
    • 派生類中對(duì)基類的虛函數(shù)進(jìn)行替換時(shí),要求派生類中說(shuō)明的虛函數(shù)與基類中被替換的虛函數(shù)之間滿足如下條件:
    • 與基類的虛函數(shù)有相同的參數(shù)個(gè)數(shù)。
    • 其參數(shù)的類型與基類的虛函數(shù)的對(duì)應(yīng)參數(shù)類型相同。
    • 其返回值或者與基類虛函數(shù)相同,或者都返回指針或引用。
    滿足上述條件的派生類的成員函數(shù),自然是虛函數(shù),可以不加 virtual.
    例如:分析下列程序輸出結(jié)果,并回答問(wèn)題:
    #include
    class A
    {
    public:
    virtual void act1();
    void act2()
    {
    act1();
    }
    };
    void A::act1()
    { cout<<”A::act1() called.”<
    class B:public A
    {
    public:
    void act1();
    }
    void B::act1()
    {cout<<”B::act1() called.”<
    void main()
    {
    B b;
    b.act2();
    }
    回答問(wèn)題:①該程序執(zhí)行后的輸出結(jié)果是什么?為什么?
    答: B::act1() called.
    因?yàn)?B 是 A 的派生類, act1() 是 A 類的虛函數(shù) , 類 B 中的 act1() 自然是虛函數(shù)。在 main() 函數(shù)中, b.act2(), 調(diào)用類 B 中的 act2() 函數(shù), B 是派生類,實(shí)際上調(diào)用 A::act2(), 而 A::act2() 函數(shù)的實(shí)現(xiàn)中調(diào)用 act1(), 由于有兩個(gè) act1() 函數(shù),并且是虛函數(shù),產(chǎn)生了動(dòng)態(tài)聯(lián)編,根據(jù)運(yùn)行情況,選擇了 B::act1();
    • 如果將 A::act2() 的實(shí)現(xiàn)改為:
    void A::act2()
    {
    this → act1();
    }
    輸出結(jié)果如何?
    答: B::act1() called.
    因?yàn)?this 是指向操作該成員函數(shù)的對(duì)象的指針。
    • 如果將 A::act2() 的實(shí)現(xiàn)改為:
    void A::act2()
    {
    a::act1();
    }
    輸出結(jié)果如何?
    答: A::act1() called.
    • 虛函數(shù)的限制:
    一個(gè)類中將所有的成員函數(shù)都盡可能 地設(shè)置為虛函數(shù)總是有益的。它除了會(huì)增加一些系統(tǒng)開銷,沒(méi)有其他壞處。但是設(shè)置虛函數(shù)應(yīng)注意:
    • 只有類的成員函數(shù)才能 說(shuō)明為虛函數(shù)。這是因?yàn)樘摵瘮?shù)僅使用于有繼承 關(guān)系的類對(duì)象,所以普通函數(shù)不能說(shuō)明為虛函數(shù)。