1. 程式人生 > >啃食c++(2)

啃食c++(2)

泛型程式設計
獨立於任何特定型別的方式編寫程式碼。
類模板入門
類模板是c++泛性程式設計的基礎,聽了接近一個小時的講課,只對老師的一句話印象比較深刻,不必造相同的輪子。恩,這句話已經概括了模板類的實質。
個人理解模板類就是我們在c++程式設計時,有些資料型別是不一樣,但是在操作這些型別的資料是,總會存在一些交集操作。這時我們通過模板類將這些相同的操作加以實現,在定義時,將這種型別的的資料定義成一個集合,可執行模板類裡已經存在的方法。
模板用於表達邏輯結構相同,但具體資料元素型別不同的資料物件的通用行為。
官方概念
人們需要編寫多個形式和功能都相似的函式,因此有了函式模板來減少重複勞動;人們也需要編寫多個形式和功能都相似的類,於是 C++ 引人了類模板的概念,編譯器從類模板可以自動生成多個類,避免了程式設計師的重複勞動。
很明顯,我的定義太過通俗!!!
定義模板類(使用模板類實現一個簡單的堆疊)

#include<iostream>
using namespace std;
enum{SIZE = 100};
template <typename T>
class stack{
    
private:
    int top ;
    T data[SIZE] ;
public:
    stack():top(0){}
    ~stack(){}
    void push(T da){
        data[top] = da ;
        top++ ;
    }
    T pop(){
        top -- ;
        return data[top] ;
    }
    int getTop(){
        return top ;
    }
};

int main(){
//定義一個存有整型數int的棧模板,當然可以定義其他簡單型別的模板類
//一個類模板,應用運算子過載來實現類的棧操作,這裡整型數比較簡單一點
    stack<int>a ;
    int i ;
    while(cin>>i){
        if(a.getTop()==SIZE||i==-1)break ;
        a.push(i);
    }
    while(a.getTop()!= 0){
        cout<<a.pop()<<endl;;
    }
}

多型
自己對於多型第一印象來源與java語言,在java語言中使用多型,就記住一點,出現基類的地方可以出現子類,基類可以通過引用子類的示例來實現呼叫父類中的特定方法滿足不同子類執行屬於他們的動作(java學的不是很好,總結的不到位,標準還是參考官方概念的好),總之多型的實現依賴與子類可以在任何情況下被其父類引用。c++裡面的多型核心沒變,和裡面的語法略有出入。
多型就指多種行為
多型指多種行為,同樣的方法呼叫而執行不同操作(支撐這一操作的基礎就是父類因引用子類物件,因此這又是建立在繼承基礎上的操作),執行不同程式碼,多型通過分離做什麼和怎麼做,從另一個角度將介面和實現進行分離。

#include<iostream>
using namespace std;
class father{
public :
    father(){}
    //防止記憶體洩露,定義父類虛擬函式,在本程式中不能體現其作用
    //但要養成這種程式設計習慣
    virtual ~father(){}
    //要實現多型的方法
    virtual void print(){}
};
//子類繼承父類
class son1:public father{
public:
    son1(){}
    ~son1(){}
    void print(){
        cout<<"the son1"<<endl ;
    }
};
class son2:public father{
public:
    son2(){};
    ~son2(){};
    void print(){
        cout<<"the son2"<<endl ;
    }
};
//父類通過外部函式引用子類,執行不同子類的同一種動作
void print(father &son){    
    son.print();
}
int main(){    
    son1 s1 ;
    son2 s2 ;
    print(s1);
    print(s2);
}

以上程式是一個多型的簡單實現,通過父類引用子類執行不同子類的方法,為什麼要為基類設定虛的解構函式呢?

#include<iostream>
using namespace std;
class father{
public :
    father(){

        cout<<"father construct "<<endl ;
    }
      ~father(){
        cout<<"father disconstruct"<<endl ;
    }
    virtual void print(){}
};
class son1:public father{
public:
    son1(){
        cout<<"son1 construct"<<endl ;
    }
    ~son1(){
        cout<<"son1 disconstruct"<<endl;
    }
    void print(){
        cout<<"the son1"<<endl ;
    }
};
class son2:public father{
public:
    son2(){
        cout<<"son2 constuct"<<endl ;
    }
    ~son2(){
        cout<<"son2 disconstruct"<<endl;
    }
    void print(){
        cout<<"the son2"<<endl ;
    }
};

void print(father *son){
    
    son->print();
}
int main(){
    
    father*s1 = new son1;
    father*s2 = new son2 ;
    print(s1);
    print(s2);
    delete s1;
    delete s2 ;
}

以下是上述程式碼執行截圖

在這裡插入圖片描述
以下是加上給基類解構函式加上virtual的執行截圖
在這裡插入圖片描述
以上很明顯,要是不給基類的解構函式加virtual那麼可能造成子類申請的記憶體不會被析構,導致記憶體洩露的風險。所以為了安全性,在任何時候都給將父類的解構函式設定為虛擬函式。