你懂得C,因此C++也不在話下

前言:C++最初誕生時,僅僅被稱做帶類的C。這說明C和C++是一衣帶水的關係,隨後C++擴充了不少特性,成爲了面向對象的一個語言,真正成了扛把子。那麼C++有什麼優點呢?舉個例子類比,一個C代碼項目就像是一個冰櫃,全部的東西都裝在一塊,且不說會不會「竄味兒」,看起來很沒條理。而C++就像是一個冰箱,有冷藏室冷凍室,冷藏室還有放雞蛋的地方,放蔬菜的地方...固然這只是其中最先的一個好處:封裝性。可是C語言無法寫出C++的特性,這就依賴於下面要介紹的C++的其餘特性。ios

一. C++ beyond C

C++擴展了一些新的特性,其中最主要的包括如下幾個:c++

  • 封裝(類)
  • 繼承
  • 多態
  • STL

接下來會簡單介紹一下每個特性,最後看一下STL的主要的容器。算法

二. 特性介紹

2.1 封裝(類)

經過抽象,類把一類東西的屬性和方法封裝到了一塊兒。這就是美其名曰「面向對象」的概念。就是代碼的組織再也不是流程控制,而是對象的組織。C語言的流程控制是經過判斷條件來跳轉執行的,而C++對象的組織則是經過繼承,多態等方式組織的。編程

class Test  
{  
    public:  
        int x_;  
        void init(int x, int y,int z);  
        void display()  
        {  
            cout<< x_ << endl;  
        };  
    private:  
        int y_;  
    protected:  
        int z_;  
};

上面是一個類的典型定義,從中能夠看出把數據和函數封裝到了一塊,並經過關鍵字public,private,protected來限制訪問權限。數組

從上面的定義看,跟C中的結構體也能夠實現相似的功能,可是C語言無法設置訪問權限,也有一些人喜歡把C寫成C++風格的。數據結構

2.2 繼承

咱們上面提到過,C語言是組織流程,因此,代碼中處處都是條件判斷和流程處理。可是在C++中,要組織的倒是一個個對象。要先抽象,定義出對象的雛形。然而,還有一個問題必須解決,C++面向的是對象,可世間對象千千萬,大千世界最不缺的就是差別,那麼千千萬不一樣的種類以及實例化的對象該怎麼管理呢?答案就是繼承和多態。繼承解決相同的部分,多態解決差別的部分。這一節就先介紹繼承。函數

繼承使得新的類沒必要徹底從新定義,而是藉助於已有的類定義,這大大的減輕了建立管理類的工做。繼承可使得新類從基類中獲取屬性和方法(public繼承時)。this

class base{
    public:
        void cacl(int n) {printf("good");}
    private:
        int i,j;

};

class next : public base{
    public:
        void mix(int m) {printf("well");}

};

關於建立新的類時是否須要採用繼承的辦法,須要注意:若是新類時基類的一種,如,哈士奇是狗的一種,哈士奇還有其餘一些屬性和方法,如賣萌;這個時候,哈士奇類能夠繼承狗這個類。另外一種狀況是,眼睛是頭的一部分,但不能說眼睛是基類,頭是派生類,由於頭顯然沒有看東西這個功能。這個時候,建立頭這個類時,應該在頭這個類種包含眼睛這個類,而不是繼承。spa

class head{
    public:
        void cacl(void);
        class eye eyes;
    private:
        int len;

};

2.3 多態

好了,要建立新類,先抽象找共性,經過繼承新的類創建起來了,然而,很快就會遇到一個問題:類的行爲千差萬別,即便對於同一個方法也會有不一樣的表現,如對於吃飯,印度人是手抓着吃,中國人是用筷子,歐美人是用刀叉。這種狀況下,若是定義一個基類,要不要定義吃飯這個方法呢?若是不定義,那麼各個派生類類就得定義本身的吃飯方法,更要命的是,一個類和另外一個類可能不光吃飯不相同,幾乎全部的方法實現起來都不相同...好比,睡覺,休閒,運動都不相同。那麼各個派生類都去定義本身的一套,繼承不就成了擺設了麼?說好的代碼重用呢?設計

這就是多態的用處,多態能夠實現對於每一個派生的類,當調用同一個方法時,實現不一樣的行爲,即調用到本身的方法實現。C++的多態能夠分爲兩種:

  • 靜態多態
  • 動態多態

所謂的靜態多態就是經過函數重載的辦法實現的,重載能夠針對操做符也能夠針對函數。用重載時,函數名字相同,參數和返回值不一樣,其實是在編譯階段根據參數的類型來肯定使用哪一個函數。

而動態多態是經過虛函數的方式實現的,也就是在基類中先定義虛函數,而後在派生類中定義本身的方法,而後覆蓋基類的方法。

#include<iostream>
using namespace std;

class Base
{
    public:
        virtual Base* FunTest()
        {
            cout << "victory" << endl;
            return this;
        }
};

class Derived :public Base
{
    public:
        virtual Derived* FunTest()
        {
            cout << "yeah" << endl;
            return this;
        }
};

int main()
{
    Base b;
    Derived d;

    b.FunTest();
    d.FunTest();

    return 0;
}

2.4 STL模版庫

爲了提升C++的開發效率,對代碼可以作到重用,STL誕生了,它一開始並非C++的一部分,STL實際上提供了泛型編程在C++上的實現。STL考慮的事情是:對於一個排序功能,不管使用哪一種數據結構,數組也好,鏈表也好;不管哪一種數據類型,int也好,float也好,都應該可以實現排序功能。爲了這個目標,STL在實現時,劃分紅了三個部分實現

  1. 容器
  2. 算法
  3. 迭代器

容器提供了經常使用的數據結構,set,map,list,vector等;算法提供了排序等幾十種算法;而迭代器呢?迭代器實際上就是要匹配容器和算法,根據不一樣的容器元素類型,採用對應的排序實現。如,數組排序和鏈表排序。

那麼再回過頭來看,STL是標準模版庫的簡寫。模版是什麼?咱們前面說到過STL是爲了提供泛型支持,回想一下會發現,函數重載是否是也解決了部分問題?(函數重載經過實現多個參數不一樣的原型,也能提供部分泛型支持)。可是,一直重載函數也不是一個有效的辦法來解決泛型支持問題,因此,模版誕生了。固然,這裏一直沒有說類模版,只提到了函數模版。模版的典型定義以下:

template<typename(或class) T>
T fuc(T x, T y)
{
    T x;
    //……
}

接下來簡單介紹一下STL提供的幾種容器:

2.4.1 幾種經常使用容器

c++中有兩種類型的容器:順序容器和關聯容器,順序容器主要有:vector、list、deque等。其中vector表示一段連續的內存地址,基於數組的實現,list表示非連續的內存,基於鏈表實現。deque與vector相似,可是對於首元素提供刪除和插入的雙向支持。關聯容器主要有map和set。map是key-value形式的,set是單值。

  • vector - 須要包含#include<vector>

    vector提供的操做主要有:
    • vec1.push_back(100);
    • vec1.size();
    • vec1.empty();
    • vec1.pop_back();
    • vec1.insert(vec1.end(),5,3);
    • vector ::const_iterator c_iter = vec1.begin();
  • list - 須要包含#include<list>

    list是一個雙向鏈表,提供的主要操做是:
    • lst1.push_back(10);
    • lst1.pop_back();
    • lst1.sort();
    • lst1.reverse();
    • lst1.remove(2);
  • map - 須要包含頭文件#include<map>

    map提供了一種存放<key,value>對兒的結構,並自動排序。主要的操做是:
    • map1.insert(make_pair<int,string>(4,"V5"));
    • map1.erase(3);
    • map1.size();

三. 總結

C++提供了面向對象的設計方法,不少特性都是圍繞着類和對象的建立,管理,使用展開的。本文只簡單介紹了C++中的一些關鍵東西,還有更多細節的東西,如構造函數,析構函數,智能指針等暫時略去不表。可是隻要掌握了C++的核心內容,細節使用隨着經驗積累,天然會心中有天地。

相關文章
相關標籤/搜索