2016年計(jì)算機(jī)二級(jí)C++復(fù)習(xí)資料:類(lèi)的設(shè)計(jì)、構(gòu)造函數(shù)和析構(gòu)函數(shù)

字號(hào):


    一、類(lèi)的設(shè)計(jì)
    1.類(lèi)的聲明
    class 類(lèi)名
    {
    private: //私有
    ...
    public: //公有
    ...
    };
    2.類(lèi)的成員
    一般在C++類(lèi)中,所有定義的變量和函數(shù)都是類(lèi)的成員。如果是變量,我們就叫它數(shù)據(jù)成員如果是函數(shù),我們就叫它成員函數(shù)。
    3.類(lèi)成員的可見(jiàn)性
    private和public訪(fǎng)問(wèn)控制符決定了成員的可見(jiàn)性。由一個(gè)訪(fǎng)問(wèn)控制符設(shè)定的可訪(fǎng)問(wèn)狀態(tài)將一直持續(xù)到下一個(gè)訪(fǎng)問(wèn)控制符出現(xiàn),或者類(lèi)聲明的結(jié)束。私有成員僅能被同一個(gè)類(lèi)中的成員函數(shù)訪(fǎng)問(wèn),公有成員既可以被同一類(lèi)中的成員函數(shù)訪(fǎng)問(wèn),也可以被其他已經(jīng)實(shí)例化的類(lèi)中函數(shù)訪(fǎng)問(wèn)。當(dāng)然,這也有例外的情況,這是以后要討論的友元函數(shù)。
    類(lèi)中默認(rèn)的數(shù)據(jù)類(lèi)型是private,結(jié)構(gòu)中的默認(rèn)類(lèi)型是public。一般情況下,變量都作為私有成員出現(xiàn),函數(shù)都作為公有成員出現(xiàn)。
    類(lèi)中還有一種訪(fǎng)問(wèn)控制符protected,叫保護(hù)成員,以后再說(shuō)明。
    4.初始化
    在聲明一個(gè)類(lèi)的對(duì)象時(shí),可以用圓括號(hào)()包含一個(gè)初始化表。
    看下面一個(gè)例子:
    #include iostream.h
    class Box
    {
    private:
    int height,width,depth; //3個(gè)私有數(shù)據(jù)成員
    public:
    Box(int,int,int);
    ~Box();
    int volume(); //成員函數(shù)
    };
    Box::Box(int ht,int wd,int dp)
    {
    height=ht;
    width=wd;
    depth=dp;
    }
    Box::~Box()
    {
    //nothing
    }
    int Box::volume()
    {
    return height*width*depth;
    }
    int main()
    {
    Box thisbox(3,4,5); //聲明一個(gè)類(lèi)對(duì)象并初始化
    cout< return 0;
    }
    當(dāng)一個(gè)類(lèi)中沒(méi)有private成員和protected成員時(shí),也沒(méi)有虛函數(shù),并且不是從其他類(lèi)中派生出來(lái)的,可以用{}來(lái)初始化。(以后再講解)
    5.內(nèi)聯(lián)函數(shù)
    內(nèi)聯(lián)函數(shù)和普通函數(shù)的區(qū)別是:內(nèi)聯(lián)函數(shù)是在編譯過(guò)程中展開(kāi)的。通常內(nèi)聯(lián)函數(shù)必須簡(jiǎn)短。定義類(lèi)的內(nèi)聯(lián)函數(shù)有兩種方法:一種和C語(yǔ)言一樣,在定義函數(shù)時(shí)使用關(guān)鍵字inline。如:
    inline int Box::volume()
    {
    return height*width*depth;
    }
    還有一種方法就是直接在類(lèi)聲明的內(nèi)部定義函數(shù)體,而不是僅僅給出一個(gè)函數(shù)原型。我們把上面的函數(shù)簡(jiǎn)化一下:
    #include iostream.h
    class Box
    {
    private:
    int height,width,depth;
    public:
    Box(int ht,int wd,int dp)
    {
    height=ht;
    width=wd;
    depth=dp;
    }
    ~Box();
    int volume()
    {
    return height*width*depth;
    }
    };
    int main()
    {
    Box thisbox(3,4,5); //聲明一個(gè)類(lèi)對(duì)象并初始化
    cout< return 0;
    }
    這樣,兩個(gè)函數(shù)都默認(rèn)為內(nèi)聯(lián)函數(shù)了。
    二、構(gòu)造函數(shù)
    什么是構(gòu)造函數(shù)?通俗的講,在類(lèi)中,函數(shù)名和類(lèi)名相同的函數(shù)稱(chēng)為構(gòu)造函數(shù)。上面的Box()函數(shù)就是構(gòu)造函數(shù)。C++允許同名函數(shù),也就允許在一個(gè)類(lèi)中有多個(gè)構(gòu)造函數(shù)。如果一個(gè)都沒(méi)有,編譯器將為該類(lèi)產(chǎn)生一個(gè)默認(rèn)的構(gòu)造函數(shù),這個(gè)構(gòu)造函數(shù)可能會(huì)完成一些工作,也可能什么都不做。
    絕對(duì)不能指定構(gòu)造函數(shù)的類(lèi)型,即使是void型都不可以。實(shí)際上構(gòu)造函數(shù)默認(rèn)為void型。
    當(dāng)一個(gè)類(lèi)的對(duì)象進(jìn)入作用域時(shí),系統(tǒng)會(huì)為其數(shù)據(jù)成員分配足夠的內(nèi)存,但是系統(tǒng)不一定將其初始化。和內(nèi)部數(shù)據(jù)類(lèi)型對(duì)象一樣,外部對(duì)象的數(shù)據(jù)成員總是初始化為0。局部對(duì)象不會(huì)被初始化。構(gòu)造函數(shù)就是被用來(lái)進(jìn)行初始化工作的。當(dāng)自動(dòng)類(lèi)型的類(lèi)對(duì)象離開(kāi)其作用域時(shí),所站用的內(nèi)存將釋放回系統(tǒng)。
    看上面的例子,構(gòu)造函數(shù)Box()函數(shù)接受三個(gè)整型擦黑素,并把他們賦值給立方體對(duì)象的數(shù)據(jù)成員。
    如果構(gòu)造函數(shù)沒(méi)有參數(shù),那么聲明對(duì)象時(shí)也不需要括號(hào)。
    1.使用默認(rèn)參數(shù)的構(gòu)造函數(shù)
    當(dāng)在聲明類(lèi)對(duì)象時(shí),如果沒(méi)有指定參數(shù),則使用默認(rèn)參數(shù)來(lái)初始化對(duì)象。
    #include iostream.h
    class Box
    {
    private:
    int height,width,depth;
    public:
    Box(int ht=2,int wd=3,int dp=4)
    {
    height=ht;
    width=wd;
    depth=dp;
    }
    ~Box();
    int volume()
    {
    return height*width*depth;
    }
    };
    int main()
    {
    Box thisbox(3,4,5); //初始化
    Box defaulbox; //使用默認(rèn)參數(shù)
    cout< cout<
    return 0;
    }
    2.默認(rèn)構(gòu)造函數(shù)
    沒(méi)有參數(shù)或者參數(shù)都是默認(rèn)值的構(gòu)造函數(shù)稱(chēng)為默認(rèn)構(gòu)造函數(shù)。如果你不提供構(gòu)造函數(shù),編譯器會(huì)自動(dòng)產(chǎn)生一個(gè)公共的默認(rèn)構(gòu)造函數(shù),這個(gè)構(gòu)造函數(shù)什么都不做。如果至少提供一個(gè)構(gòu)造函數(shù),則編譯器就不會(huì)產(chǎn)生默認(rèn)構(gòu)造函數(shù)。
    3.重載構(gòu)造函數(shù)
    一個(gè)類(lèi)中可以有多個(gè)構(gòu)造函數(shù)。這些構(gòu)造函數(shù)必須具有不同的參數(shù)表。在一個(gè)類(lèi)中需要接受不同初始化值時(shí),就需要編寫(xiě)多個(gè)構(gòu)造函數(shù),但有時(shí)候只需要一個(gè)不帶初始值的空的Box對(duì)象。
    #include iostream.h
    class Box
    {
    private:
    int height,width,depth;
    public:
    Box() { //nothing }
    Box(int ht=2,int wd=3,int dp=4)
    {
    height=ht;
    width=wd;
    depth=dp;
    }
    ~Box();
    int volume()
    {
    return height*width*depth;
    }
    };
    int main()
    {
    Box thisbox(3,4,5); //初始化
    Box otherbox;
    otherbox=thisbox;
    cout< return 0;
    }
    這兩個(gè)構(gòu)造函數(shù)一個(gè)沒(méi)有初始化值,一個(gè)有。當(dāng)沒(méi)有初始化值時(shí),程序使用默認(rèn)值,即2,3,4。
    但是這樣的程序是不好的。它允許使用初始化過(guò)的和沒(méi)有初始化過(guò)的Box對(duì)象,但它沒(méi)有考慮當(dāng)thisbox給otherbox賦值失敗后,volume()該返回什么。較好的方法是,沒(méi)有參數(shù)表的構(gòu)造函數(shù)也把默認(rèn)值賦值給對(duì)象。
    class Box
    {
    int height,width,depth;
    public:
    Box()
    {
    height=0;width=0;depth=0;
    }
    Box(int ht,int wd,int dp)
    {
    height=ht;width=wd;depth=dp;
    }
    int volume()
    {
    return height*width*depth;
    }
    };
    這還不是的方法,更好的方法是使用默認(rèn)參數(shù),根本不需要不帶參數(shù)的構(gòu)造函數(shù)。
    class Box
    {
    int height,width,depth;
    public:
    Box(int ht=0,int wd=0,int dp=0)
    {
    height=ht;width=wd;depth=dp;
    }
    int volume()
    {
    return height*width*depth;
    }
    };
    三、析構(gòu)函數(shù)
    當(dāng)一個(gè)類(lèi)的對(duì)象離開(kāi)作用域時(shí),析構(gòu)函數(shù)將被調(diào)用(系統(tǒng)自動(dòng)調(diào)用)。析構(gòu)函數(shù)的名字和類(lèi)名一樣,不過(guò)要在前面加上 ~ 。對(duì)一個(gè)類(lèi)來(lái)說(shuō),只能允許一個(gè)析構(gòu)函數(shù),析構(gòu)函數(shù)不能有參數(shù),并且也沒(méi)有返回值。析構(gòu)函數(shù)的作用是完成一個(gè)清理工作,如釋放從堆中分配的內(nèi)存。
    我們也可以只給出析構(gòu)函數(shù)的形式,而不給出起具體函數(shù)體,其效果是一樣的,如上面的例子。但在有些情況下,析構(gòu)函數(shù)又是必需的。如在類(lèi)中從堆中分配了內(nèi)存,則必須在析構(gòu)函數(shù)中釋放。