關(guān)于拷貝構(gòu)造函數(shù)和賦值運(yùn)算符

字號:

class CExample
    {
    public:
    CExample(){pBuffer=NULL; nSize=0;}
    ~CExample(){delete pBuffer;}
    void Init(int n){ pBuffer=new char[n]; nSize=n;}
    private:
    char *pBuffer; //類的對象中包含指針,指向動(dòng)態(tài)分配的內(nèi)存資源
    int nSize;
    };
    這個(gè)類的主要特點(diǎn)是包含指向其他資源的指針。
    pBuffer指向堆中分配的一段內(nèi)存空間。
    一、拷貝構(gòu)造函數(shù)
    int main(int argc, char* argv[])
    {
    CExample theObjone;
    theObjone.Init40);
    //現(xiàn)在需要另一個(gè)對象,需要將他初始化稱對象一的狀態(tài)
    CExample theObjtwo=theObjone;
    ...
    }
    語句"CExample theObjtwo=theObjone;"用theObjone初始化theObjtwo。
    其完成方式是內(nèi)存拷貝,復(fù)制所有成員的值。
    完成后,theObjtwo.pBuffer==theObjone.pBuffer。
    即它們將指向同樣的地方,指針雖然復(fù)制了,但所指向的空間并沒有復(fù)制,而是由兩個(gè)對象共用了。這樣不符合要求,對象之間不獨(dú)立了,并為空間的刪除帶來隱患。
    所以需要采用必要的手段來避免此類情況。
    回顧以下此語句的具體過程:首先建立對象theObjtwo,并調(diào)用其構(gòu)造函數(shù),然后成員被拷貝。
    可以在構(gòu)造函數(shù)中添加操作來解決指針成員的問題。
    所以C++語法中除了提供缺省形式的構(gòu)造函數(shù)外,還規(guī)范了另一種特殊的構(gòu)造函數(shù):拷貝構(gòu)造函數(shù),上面的語句中,如果類中定義了拷貝構(gòu)造函數(shù),這對象建立時(shí),調(diào)用的將是拷貝構(gòu)造函數(shù),在拷貝構(gòu)造函數(shù)中,可以根據(jù)傳入的變量,復(fù)制指針?biāo)赶虻馁Y源。
    拷貝構(gòu)造函數(shù)的格式為:構(gòu)造函數(shù)名(對象的引用)
    提供了拷貝構(gòu)造函數(shù)后的CExample類定義為:
    class CExample
    {
    public:
    CExample(){pBuffer=NULL; nSize=0;}
    ~CExample(){delete pBuffer;}
    CExample(const CExample&); //拷貝構(gòu)造函數(shù)
    void Init(int n){ pBuffer=new char[n]; nSize=n;}
    private:
    char *pBuffer; //類的對象中包含指針,指向動(dòng)態(tài)分配的內(nèi)存資源
    int nSize;
    };
    CExample::CExample(const CExample& RightSides) //拷貝構(gòu)造函數(shù)的定義
    {
    nSize=RightSides.nSize; //復(fù)制常規(guī)成員
    pBuffer=new char[nSize]; //復(fù)制指針指向的內(nèi)容
    memcpy(pBuffer,RightSides.pBuffer,nSize*sizeof(char));
    }
    這樣,定義新對象,并用已有對象初始化新對象時(shí),CExample(const CExample& RightSides)將被調(diào)用,而已有對象用別名RightSides傳給構(gòu)造函數(shù),以用來作復(fù)制。
    原則上,應(yīng)該為所有包含動(dòng)態(tài)分配成員的類都提供拷貝構(gòu)造函數(shù)。
    拷貝構(gòu)造函數(shù)的另一種調(diào)用。