1、繼承ios
一、 定義和做用編程
C++繼承機制是利用已有的數據類型來定義新的數據類型,用來派生新類的類稱爲基類或父類,由已存在的類派生出的新類稱爲派生類或子類。派生類不只擁有新定義的成員,同時擁有基類的成員。函數
一個派生類能夠從一個基類或多個基類派生,前者稱爲單繼承,後者稱爲多繼承。spa
1)單繼承的定義格式以下:指針
class<派生類名>:<繼承方式><基類名>code
{對象
<派生類新定義成員>繼承
};接口
2)多繼承的定義格式以下:ci
class<派生類名>:<繼承方式1><基類名1>,<繼承方式2><基類名2>,…
{
<派生類新定義成員>
};
繼承能夠擴展已存在的代碼,目的是代碼複用。
二、 繼承方式
公有繼承(public)、私有繼承(private)、保護繼承(protected)是經常使用的三種繼承方式。
1)公有繼承(public)
公有繼承的特色是基類的公有成員和保護成員做爲派生類的成員時,它們都保持原有的狀態,而基類的私有成員仍然是私有的,不能被這個派生類的子類所訪問。
2)私有繼承(private)
私有繼承的特色是基類的公有成員和保護成員都做爲派生類的私有成員,而且不能被這個派生類的子類所訪問。
3)保護繼承(protected)
保護繼承的特色是基類的全部公有成員和保護成員都成爲派生類的保護成員,而且只能被它的派生類成員函數或友元訪問,基類的私有成員仍然是私有的。
在不一樣的繼承方式下,派生類對基類的成員訪問權限以下表所示:
繼承方式\成員類型 |
public |
protected |
private |
public |
public |
protected |
不可見 |
protected |
protected |
protected |
不可見 |
private |
private |
private |
不可見 |
若是繼承方式,class默認採用私有繼承,而struct默認的是public繼承。
2、多態
一、 定義和做用
C++多態性能夠簡單地歸納爲「一個接口,多種方法」。父類對象能夠根據當前子類對象賦值的特性在運行時決定調用的函數,容許子類類型的指針賦值給父類類型的指針。多態是面向對象編程領域的核心概念。
多態的目的爲了接口重用,不管傳遞過來的對象屬於哪一個類,函數均可以經過同一個接口調用到適應不一樣對象的實現方法。
二、 實現方式
C++中有兩種實現多態的方式,分別是重載和覆蓋。
1) 重載
重載是容許有多個同名的函數,但這些函數的參數列表不一樣,如參數個數不一樣和參數類型不一樣等。這些同名函數的調用在編譯過程就肯定了調用地址,編譯器會根據這些函數的不一樣參數列表,將同名函數的名稱作修飾,從而生成一些不一樣名稱的預處理函數,屬於靜態綁定(早綁定)。
例如,有兩個同名函數: void func(int num)和void func(string name),那麼編譯器作過修飾後的函數名稱多是int_func和str_func。
實際,重載只是一種語言特性,與多態無關,與面向對象也無關。
2) 覆蓋
覆蓋是指子類對父類的虛函數重定義。虛函數是在通常函數前面加上virtual。經過聲明父類的指針,利用該指針指向一個子類對象,調用相應的虛函數,能夠根據指向的子類的不一樣而實現不一樣的方法。對虛函數的調用在編譯過程當中不能肯定,在運行時才能肯定,屬於動態綁定(晚綁定)。
三、 純虛函數
純虛函數是在父類中聲明的未定義的虛函數,函數原型後加上「=0」,如virtual void func()=0。編譯器要求在任何子類中都須要重定義純虛函數,以實現多態性。
含有純虛函數的類稱爲抽象類,不能定義抽象類的對象。
三、 示例
#include <iostream> #include <stdlib.h> #include <time.h> using namespace std; class Father { public: Father(){} ~Father(){} void func() { cout << "1" << endl; } virtual void function() { cout << "2" << endl; } }; class Child : public Father { public: Child(){} ~Child(){} void func() { cout << "3" << endl; } void function() { cout << "4" << endl; } }; int main() { Father father; Child child; father.func(); father.function(); child.func(); child.function(); Father *fa = new Father(); fa = &father; fa->func(); fa->function(); fa = &child; fa->func(); fa->function(); return 0; }
執行結果:1,2,3,4 1,2,1,4 3,2,3,4
執行結果能夠看出,父類對象在調用function()函數時根據子類對象選擇了不一樣的方法。
3、重載
一、 定義
重載是容許有多個同名的函數,但這些函數的參數列表不一樣,如參數個數不一樣和參數類型不一樣等。
重載與重寫的區別就在因而否覆蓋,重寫通常多發生在不一樣的類且存在繼承關係之間,而重載可能是在一個類裏或者一塊代碼段裏。
二、 實現方式
重載函數的函數名必須相同,參數列表必須不一樣,返回值能夠相同也能夠不一樣。例如,void func(int num)和void func(string name)就屬於重載。
三、 示例
#include <iostream> #include <stdlib.h> #include <time.h> using namespace std; void func(int num) { cout << num << endl; } void func(string name) { cout << name.c_str() << endl; } int main() { int num = 1; string name = "liu"; func(num); func(name); return 0; }
執行結果:1 liu
執行結果能夠看出,在調用func()函數時會根據參數的不一樣選擇相應的函數實現。
4、訪問修飾符
一、 定義
public:全部範圍都能訪問;
protected:類自身和派生類能訪問;
private:類自身能訪問。