C++中的抽象類


一,抽象類

1.純虛函數的概念

  純虛函數是在父類中定義了一個只有聲明而沒有實現的函數,即使給出了純虛函數的實現,那么編譯器也會忽略。

2.純虛函數的說明形式

  virtual  返回值類型   函數名稱(參數列表)  =  0;

3.純虛函數的意義

  純虛函數只存在了函數的聲明,而不存在函數的實現,在繼承中為子類提供了一個統一的接口,每一個子類對象都可以去實現它,在多態特性中便會根據需要的子類對象而調用相應的子類業務。

4.抽象類的概念

  含有純虛函數的類稱為抽象類。

5.抽象類示例

# include<iostream>

using namespace std;

/* 動物類 */
class Animal
{
public:
    /* 純虛函數 */
    virtual void eat() = 0;
    /* 虛析構函數:保證子類的析構函數被調用正確 */
    ~Animal() {};
};

/* 狗類 */
class Dog:public Animal
{
public:
    virtual void eat()
    {
        cout << "狗吃骨頭..." << endl;
    }
};

/* 貓類 */
class Cat :public Animal
{
public:
    virtual void eat()
    {
        cout << "貓吃魚..." << endl;
    }
};

/* 抽象類指針做函數返回值 */
Animal * get()
{
    Animal * animal = new Cat;
    return animal;
}

/* 抽象類引用作函數參數 */
void set(Animal& animal)
{
    animal.eat();
}

int main()
{
    /* 抽象類指針 */
    Animal * animal1 = new Dog();
    animal1->eat();
    delete animal1;

    /* 抽象類引用 */
    Cat cat;
    Animal& animal2 = cat;
    animal2.eat();

    /* 抽象類指針做函數返回值 */
    Animal * animal3 = get();
    animal3->eat();
    delete animal3;

    /* 抽象類引用作函數參數 */
    Dog dog;
    set(dog);

    return 0;
}

 5.抽象類特點

  • 抽象類不允許創建對象。
  • 抽象類元素不能作為函數的返回值,不能作為函數的參數。
  • 抽象類的指針和引用可以做函數參數,可以做返回值,可以指向子類對象。
  • 抽象類的子類必須去實現純虛函數,如果不實現,該類還是抽象類。

6.接口

  在Java中存在接口的概念,並且Java中只允許單繼承,但是允許接口的多實現。C++中的多繼承存在二義性詬病,不建議使用,而且C++也沒有提供接口的概念,但是我們可以使用抽象類來模擬接口,因此利用這一特性,我們可以使用抽象類模擬的繼承實現接口的多實現,借用C++的多繼承模擬出來的接口的多實現,即解決了C++多繼承的二義性詬病,又極好的實現了大多數現在面向對象語言的接口的功能。

7.接口的案例

# include<iostream>
using namespace std;

class Interface
{
public:
    virtual void print() = 0;
};

class Impl1 :public Interface
{
public:
    void print()
    {
        cout << "Impl1的實現" << endl;
    }
};

class Impl2 :public Interface
{
public:
    void print()
    {
        cout << "Impl2的實現" << endl;
    }
};

int main()
{
    Interface * i1 = new Impl1;
    i1->print();

    Interface * i2 = new Impl2;
    i2->print();

    return 0;
}

二,C語言實現多態

1.函數的三要素

  函數的三要素為:函數名稱,函數參數,函數返回值。

2.函數指針的概念

  在C語言中我們可以定義指向函數的指針,被稱為函數指針。函數的名稱是函數的入口地址。

3.函數指針的定義

  函數指針的定義格式:函數返回值類型  (* 函數指針名稱)(函數參數列表);

4.函數的回調本質

  函數的回調,就是利用了函數的指針實現的。首先我們提前約定一個格式,把函數的參數列表和函數的返回值類型規定好,又因為函數的名稱是函數的入口地址,所以我們在函數指針使用的時候傳入函數的名稱(即函數的入口地址)就可以動態的調用符合約定格式的函數。

5.函數指針及函數的回調示例

# include<iostream>
using namespace std;

/* 定義加法函數 */
int add(int a, int b)
{
    return a + b;
}
/* 定義減法函數 */
int sub(int a, int b)
{
    return a - b;
}
/* 定義回調函數 */
int execFun(int(*fun)(int a, int b),int p_a,int p_b)
{
    return fun(p_a, p_b);
}

int main()
{
    /* 定義一個函數返回值為int,函數參數有兩個int類型的函數指針 */
    int(*fun)(int a, int b);
    /* 動態使得函數指針指向一個函數 */
    fun = add;
    /* 調用函數指針進行運算 */
    int r1 = fun(1, 2);
    cout << "r1 = " << r1 << endl;


    /* 回調函數:我們只需要傳遞要調用的函數和要計算的數值即可,回調函數幫我們自動調用並返回結果 */
    fun = sub;
    int r2 = execFun(fun, 100, 200);

    return 0;
}

 

6.函數回調的意義及多態

  函數的回調最大的意義是在於不在同一個文件中,我們可以在一個文件中進行回調函數的約定,在另個文件中書寫具體的函數,當在代碼運行時,我們動態的改變函數指針使其指向不同的調用函數,也就實現了C語言的多態。


免責聲明!

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



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