1. 程式人生 > >C++的六個函數

C++的六個函數

創建 分配 資源 回收 PE delet 賦值 pan 傳遞

一、構造函數

在C++中,構造函數是六個函數中的第一個,當一個對象被創建時,在它的整個周期中,是一個由生到死的

過程,即構造函數創建對象,析構函數析構對象。在對象被創建時,調用構造函數創建一個對象,這是對象的創

建過程。在C++中,當你創建一個對象時需要調用構造函數創建對象,在類中,有默認的構造函數,當然你也可

以去使用構造函數去創建對象,對數據進行初始化。看下面的例子:

class Base 
{
   public:
       Base()
       {}
       Base(int a=0):num(a)
       {}
       Base(int a=0,int
b=0):num(a),age(b) {} Base(int a=0,int b=0,double c=0.0):num(a),age(b),slaroy(c) {} private: int num; int age; double slaroy; };

在上面的構造函數中,構造函數必須與類名相同,構造函數是無類型的,第一個構造函數是默認的構造函數,

第二個構造函數是只對一個數據成員進行初始化,其它的數據成員是隨機值。第二個構造函數是對兩個數據成員

進行初始化,其它的數據成員為隨機值。第三個構造函數是對所有的數據成員進行初始化。

二、析構函數

在C++中,構造函數是創建一個對象時,那麽析構函數則是這個對象由生到死的死亡過程。同時析構函數也

析構對象時可以將已經分配的內存空間進行回收。

class Base
{
   public:
       Base()
       {}
       Base()
       {
          p= new char[strlen("default")+1];
          strcpy(p,"default");
       }
       ~Base()
       {
           if(p != NULL)
           {
              
delete[] p; p=NULL; } } private: char *p; };

析構函數如上所示,它無類型、無參數、無返回值,如果在構造對象時沒有進行空間的開辟內存的分配時,那麽

析構函數如同默認的析構函數一樣,如果進行了內存的分配時,當一個對象被析構時同時還要對其所分配的內存進行

回收,否則就會造成內存泄漏。

三、拷貝構造函數

在C++中,如果在構造函數中有申請內存的操作,且在其他函數中出現對象的拷貝,那麽就會需要拷貝構造函數。

class Base
{
   public:
       Base()
       {}
       Base()
       {
          p= new char[strlen("default")+1];
          strcpy(p,"default");
       }
       Base(const Base &s)
       {
         p= new char[strlen(s.p)+1];
         strcpy(p,s.p);
       }
       ~Base()
       {
           if(p != NULL)
           {
              delete[] p;
              p=NULL;
           }
       }
   private:
       char *p;
}; 
int main()
{
   Base a;
   Base b(a);
   return 0;
}

由於在主函數中出現了對對象的拷貝賦值,那麽就需要拷貝構造函數,如果沒有拷貝構造函數,則會使用默認的

拷貝構造函數,那麽此時進行的是淺拷貝,那麽會產生析構函數對內存重復釋放的錯誤。那麽此時就需要進行深拷貝

操作,重新編寫拷貝構造函數對對象進行拷貝賦值。而在編寫拷貝構造函數時要註意參數必須是“&”引用傳遞,否則

則是語法錯誤。

四、賦值函數

在C++中,賦值函數為第四個函數,如果在構造函數中有申請內存的操作,且在其他程序中有兩個對象直接或間接

進行賦值操作,就需要賦值函數。

class Base
{
   public:
       Base()
       {}
       Base()
       {
          p= new char[strlen("default")+1];
          strcpy(p,"default");
       }
       Base(const Base &s)
       {
         p= new char[strlen(s.p)+1];
         strcpy(p,s.p);
       }
       Base& operator=(const Base &s)
       {
           if(&s==this)
              return *this;
           delete[] p;
           p= new char[strlen(s.p)+1];
           strcpy(p,s.p);
           return *this;
        }
       ~Base()
       {
           if(p != NULL)
           {
              delete[] p;
              p=NULL;
           }
       }
   private:
       char *p;
}; 
int main()
{
   Base a,c;
   Base b(a);
   c=a;
   return 0;
}

由於在主函數中進行了對象的賦值操作,如果沒有對“=”運算符進行重載定義,則會產生兩次釋放同一個內存的

操作的錯誤。在“=”重載操作中,如果涉及到指針操作,則必須判斷兩個對象是否為同一個對象即自賦值操作,否則

當進行釋放指針的操作時,就可能產生錯誤。然後要用delete釋放原有的內存資源,否則將造成內存泄漏。

五、對一般對象的取址函數

在C++中,對一般對象的取址函數為第五個函數。

class Base
{
   public:
       Base* operator&()
       {
          return this;
       }
}; 

在一般對象的取址函數是直接返回該對象的地址,則為取其地址。

六、對常對象的取址函數

在C++中,對常對象的取址函數為第六個函數。

class Base
{
   public:
       const Base* operator&() const
       {
          return this;
       }
};

在常對象的取址函數也是直接返回該常對象的地址,則為取其地址。

C++的六個函數