1. 程式人生 > >預設建構函式 new和delete 解構函式 私有成員和保護成員

預設建構函式 new和delete 解構函式 私有成員和保護成員

1、預設建構函式

定義預設建構函式的方法有兩種:

    (1)如果沒有提供任何建構函式,C++將建立預設建構函式。該預設建構函式不接受任何引數,也不執行任何操作。格式如下:

              Stonewt::Stonewt(){ }    //implicit default constructor 

      可以顯示的定義該預設建構函式,使用它來設定特定的值。如:

Stonewt::Stonewt()  //expicit default constructor
{
stone=0;
...
}

       (2) 帶引數的建構函式也可以是預設建構函式,只要所有引數都有預設的值。例如,Stonewt類可以包含下列內聯建構函式:

               Stonewt(int n=0){stone=n;}

        只能存在一個預設建構函式。

 

        通常應初始化所有的物件,以確保所有成員一開始就有已知的、合理的值。因此,預設建構函式通常給所有成員提供隱式初始值。

例如,下面是為Stock類定義的一個預設建構函式:

Stock::Stock()
{
    std::strcpy(company,"no name");
    shares=0;
    share_val=0.0;
    total_val=0.0;
}

 

建構函式的初始化的幾種方法:

方法一:
   Stock stock1("test",2,2.0);
方法二:
   Stock stock2=Stock("test2",3,3.0);
方法三:
   Stock * stock3=new Stock("test3",4,4.0);
方法四:
   stock2=stock1;//將物件stock1賦值給stock2,stock1的內容將覆蓋stock2的內容。



對於只有一個引數的建構函式,如Stock(int n),其初始化:
Stock stock1(23);
Stock stock2=Stock(34);
Stock stock3=54;

 

不要試圖將類成員名稱用作建構函式的引數,如下:

Stock::Stock(const char * company,int shares,double share_val)
{
...
}

   這是錯誤的。建構函式的引數表示的不是類成員,而是賦給類成員的值。因此引數名不能與類成員相同,否則最終的程式碼將是這樣的:
     shares=shares;

  為避免這種混亂,通常的做法是在資料成員名中使用m_字首:
class Stock
{

private:
       int m_shares;
...


      (3)建構函式是不能繼承的,即在建立派生類時,必須呼叫派生類的建構函式。不過,派生類建構函式通常使用成員初始化列表句法來呼叫基類建構函式,以建立派生物件的基類部分。如果派生類建構函式沒有使用初始化列表句法顯示呼叫基類建構函式,將使用基類的預設建構函式。在繼承鏈中,每個類都可以使用成員初始化列表將資訊傳遞迴相鄰的基類。

2、new和delete 

class Act{...};
...
Act nice;  //external object
...
int main()
{
    Act *pt=new Act;  //dynamic object
    {
        Act up;  //automatic object
        ...
    }        //-------------------------------a
    delete pt;  //----------------------------b
    ...
}            //-------------------------------c

a、當執行到達定義資料塊的結尾時,呼叫動態物件up的解構函式;

b、當delete操作符用於指標pt應用時,呼叫動態物件*pt的解構函式;

c、當執行到達整個程式的結尾時,呼叫靜態物件nice的解構函式

 

3、解構函式

在下述情況下解構函式將被呼叫:

  • 如果物件是動態變數,則當執行完定義該物件的程式塊時,將呼叫該物件的解構函式。
  • 如果物件是靜態變數(外部、靜態、靜態外部或來自名稱空間),則在程式結束時將呼叫物件的解構函式。
  • 如果物件是new建立的,則僅當你顯示地使用delete刪除物件時,其解構函式才會被呼叫。
  • 按值傳遞物件時,會生成臨時拷貝,即呼叫複製建構函式,然後呼叫解構函式。
  • 返回物件時,會生成返回物件的臨時拷貝,即呼叫複製建構函式,然後呼叫解構函式刪除臨時拷貝。

         函式mian()結束時,在main()函式中的區域性變數將消失。由於這種自動變數被放在堆疊中,因此最後建立的物件將最先被刪除,最先被建立的物件將最後被刪除。

         程式建立派生類物件時,將首先呼叫基類的建構函式,然後呼叫派生類的建構函式;程式刪除物件時,將首先呼叫派生類的解構函式,然後呼叫基類的解構函式。

4、私有成員和保護成員

    對派生類而言,保護成員類似於公有成員;但對於外部而言,保護成員會私有成員類似。派生類可以直接訪問基類的保護成員,但只能通過基類的成員函式來訪問私有成員。因此,將基類成員設定為私有的可以提高安全性,而將他們設定為保護成員則可簡化程式碼的編寫工作,並提高訪問速度。