Pin-Jiun / Programming-Language-CPP

It's the note/experience about C++, and I have the basic ability of C.
0 stars 0 forks source link

6-Virtual Functions, Pure Virtual Functions and Abstract Classes #7

Open Pin-Jiun opened 1 year ago

Pin-Jiun commented 1 year ago

Virtual Function

使用pointer或reference存取derived class物件時,且pointer指向的類型是 base class 如果衍生類別覆蓋了基礎類別中的method,通過上述指標或參照呼叫該方法時,可以有兩種結果:

呼叫到基礎類別的方法:編譯器根據指標或參照的類型決定,稱作 early binding 呼叫到衍生類別的方法:執行時系統根據物件的實際類型決定,稱作 dynamic binding or late binding


early binding

首先使用指針建立物件

#include <iostream>
using namespace std;

class Student{
public:
    void Hello(){
        cout << "I'm a student.\n";
    }
};

class ChemsitryStudent : public Student{
public:
    void Hello(){
        cout << "I'm a student major in chemistry.\n";
    }
};

int main()
{
    Student *p_Amy = new ChemsitryStudent;
    p_Amy -> Hello();
}

p_Amy會指向class為Student的物件,故output出

I'm a student.

dynamic binding or late binding

將bass class的class Student中的void Hello()加上修飾字virtual 此時由於base class中的 Hello() 被宣告為 virtual ,此時會告訴compilier Hello() 這個method會進行 dynamic binding

class Student{
public:
    virtual void Hello(){  //add virtual
        cout << "I'm a student.\n";
    }
};

第一種情況derived class implement

class ChemsitryStudent : public Student{
public:
    void Hello(){
        cout << "I'm a student major in chemistry.\n";
    }
};

int main()
{
    Student *p_Amy = new ChemsitryStudent;
    p_Amy -> Hello();
}

此時程式執行時會連到ChemsitryStudent的Hello() output

I'm a student major in chemistry.

第二種情況derived class 沒有 implement

class ChemsitryStudent : public Student{
public:
};

int main()
{
    Student *p_Amy = new ChemsitryStudent;
    p_Amy -> Hello();
}

此時程式執行時連不到ChemsitryStudent的Hello(),故會連結到Student的virtual void Hello() output

I'm a student major in chemistry.

Pure Virtual Functions

知道子類別一定會衍生至此父類別,且子類別一定會有此function但表現的型態不同,故父類別不實作此function 將實作function的工作交給derived class,而且derived class一定要實作

virtual return_type function() = 0; virtual void Hello() = 0;

class Student{
public:
    virtual void Hello() = 0 ;
};

class ChemsitryStudent : public Student{
public:
    void Hello(){
        cout << "I'm a student major in chemistry.\n";
    }
};

int main()
{
    Student *p_Amy = new ChemsitryStudent;
    p_Amy -> Hello();
}

output I'm a student major in chemistry.

Abstract Classes

含有pure virtual function的class Student 無法 實作Abstract Class的物件,必須實作其subclass


多型的表現

class Student{
public:
    virtual void Hello() = 0 ;
};

class MathStudent : public Student{
public:
    void Hello(){
        cout << "I'm a student major in Math.\n";
    }
};

class ChemsitryStudent : public Student{
public:
    void Hello(){
        cout << "I'm a student major in chemistry.\n";
    }
};

int main()
{
    Student *p_Amy = new MathStudent;
    Student *p_Jim = new ChemsitryStudent;
    Student *p_Name[]={p_Amy,p_Jim};

    for(int i = 0 ; i <=2 ; i++){
        p_Name[i] -> Hello();
    }
}

雖然pointer皆指向 Student 這個class,但是表現出來的method不同

I'm a student major in Math.
I'm a student major in chemistry.