C++中的純虛函數


---恢復內容開始---

在C++中的一種函數申明被稱之為:純虛函數(pure virtual function).它的申明格式如下

class CShape
{
public:
    virtual void Show()=0;
};

在什么情況下使用純虛函數(pure vitrual function)?

1,當想在基類中抽象出一個方法,且該基類只做能被繼承,而不能被實例化;
2,這個方法必須在派生類(derived class)中被實現;
   如果滿足以上兩點,可以考慮將該方法申明為純虛函數(pure virtual function).
#include <iostream>
#include <cstdlib>
#include <cstdio>

using namespace std;


class abstractcls
{
public:
    abstractcls(float speed,int total)   //構造函數
    {
        this->speed = speed;
        this->total = total;
    }

    virtual void showmember()= 0;    //純虛函數的定義
protected:
    float speed;
    int total;
};

class car : public abstractcls
{
public:
    car(int aird,float speed,int total):abstractcls(speed,total)
    {
        this->aird = aird;
    }

    virtual void showmember()
    {
        cout << speed <<"--------" <<total <<"-----------"<<aird<<endl;
    }
protected:
    int aird;
};
int main()
{
    car b(250,150,4);
    b.showmember();
    return 0;
}

下面我們看一道某公司的面試的筆試題(含金量到底有多少??)

#include <iostream>
#include <cstdio>

using namespace std;

class A
{
public:
    void foo()
    {
        printf("1\n");
    }
    virtual void fuu()
    {
        printf("2\n");    
    }
};

class B:public A
{
public :
    void foo()
    {
        printf("3\n");
    }
    void fuu()
    {
        printf("4\n");
    }
};

int main()
{
    A a;
    B b;
    
    A *p = &a;
    cout<< "p->foo()---" ; p->foo() ; 
    cout<<"p->fuu()---";p->fuu();    

    cout <<"-------向上轉型-----------"<<endl;
    p=&b;
    cout<<"p->foo()---";p->foo();    
    cout<<"p->fuu()---";p->fuu();    
    
    cout <<"--------向下轉型----------"<<endl;
    
    B *ptr =(B *)&a;
    cout<<"ptr->foo()----";ptr->foo();
    cout<<"ptr->fuu()-----";ptr->fuu();
    return 0;
}

先不要看答案,看自己能否作對??

 

下面進行詳細分析一下為什么結果是這樣的??你全做對了沒??

      第一個p->foo()和p->fuu()都很好理解,本身是基類指針,指向的又是基類對象,調用的都是基類本身的函數,因此輸出結果就是1、2。
  第二個輸出結果就是1、4。p->foo()和p->fuu()則是基類指針指向子類對象,正式體現多態的用法,p->foo()由於指針是個基類指針,指向是一個固定偏移量的函數,因此此時指向的就只能是基類的foo()函數的代碼了,因此輸出的結果還是1。而p->fuu()指針是基類指針,指向的fuu是一個虛函數,由於每個虛函數都有一個虛函數列表,此時p調用fuu()並不是直接調用函數,而是通過虛函數列表找到相應的函數的地址,因此根據指向的對象不同,函數地址也將不同,這里將找到對應的子類的fuu()函數的地址,因此輸出的結果也會是子類的結果4.

 

  第三個並不是很理解這種用法,從原理上來解釋,由於B是子類指針,雖然被賦予了基類對象地址,但是ptr->foo()在調用的時候,由於地址偏移量固定,偏移量是子類對象的偏移量,於是即使在指向了一個基類對象的情況下,還是調用到了子類的函數,雖然可能從始到終都沒有子類對象的實例化出現。

  第四個:而ptr->fuu()的調用,可能還是因為C++多態性的原因,由於指向的是一個基類對象,通過虛函數列表的引用,找到了基類中foo()函數的地址,因此調用了基類的函數。由此可見多態性的強大,可以適應各種變化,不論指針是基類的還是子類的,都能找到正確的實現方法。

 

小結:1.有virtual才可能發生多態現象2.不發生多態(無virtual)調用就按原類型調用


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM