1. 程式人生 > >const引數,const返回值與const函式

const引數,const返回值與const函式

       在C++程式中,經常用const 來限制對一個物件的操作,例如,將一個變數定義為const 的:

const  int  n=3;

則這個變數的值不能被修改,即不能對變數賦值。

       const 這個關鍵字經常出現在函式的定義中,而且會出現在不同的位置,比如:

               int  strcmp (const  char  *str1,const   char  *str2);

              const   int  & min (int  &, int  &);

              void  printMessage (char  *msg) const

;

1.const 引數

出現在函式引數中的const 表示在函式體中不能對這個引數做修改。比如上面的例子中strcmp() 函式用來比較兩個字串的大小,在函式體中不應該改變兩個引數的值,所以將它定義為是const 的。const 通常用來限制函式的指標引數,引用和陣列引數,而一般形式的引數因為形參和實參本來就不在同一記憶體空間,所以對形參的修改不會影響實參,因此也沒有必要限制函式體不能對引數進行修改。

        下面是一些使用函式 const 引數的例子:

(1)  函式 strcpy() 將 src 字串的內容複製到 targ 字串中,為保證 src 字串不被修改,將它定義為 const 引數:

               void  strcpy ( const  char  *src , char  * targ);

(2)  函式 max() 從陣列 array 中找出具有最大值的陣列元素並返回這個最大元素的值,為保證陣列元素不會在函式中被修改, 將它定義為 const  引數:

              int  max ( const  int  array[ ],  int  size);

(3)  函式 outputObject( ) 將類 Myclass 的物件 obj 的內容輸出。物件定義為 const  引用,即可以保證物件不會在函式體中有所改變,又可以節省物件傳遞的開銷:

              void  outputObject ( const   Myclass  &obj) ;

PS:

       const 指標可以接受const 和非 const 地址,但是非const 指標只能接受非const 地址。所以const  指標的能力更強一些,所以儘量多用const 指標,這是一種習慣。

2. const 返回值

        函式返回值為 const  只有用在函式返回為引用的情況。 函式返回值引用常量表示不能將函式呼叫表示式作為左值使用。例如前面講的返回引用的函式 min( )。

        int  & min ( int  &i,  int  &j); 

可以對函式呼叫進行賦值,因為它返回的是左值:  min ( a ,  b )=4;

但是,如果對函式的返回值限定為 const  的:const  int  & min ( int & i, int  &j );

那麼,就不能對 min ( a, b ) 呼叫進行賦值了。

3. const 函式

         在類中,可以為類的成員函式進行如下形式的定義:

class  classname {

          int  member ;

  public:

         int  getMember ( ) const;

};

       這裡,在函式定義頭後面加上的 const 表示這個函式是一個“只讀函式”,函式不能改變類物件的狀態,不能改變物件的成員變數的值。如在函式體中不能這麼寫

    classname :: getmember( )

   {  member =4 ; 

     return  member;

   }

另外,const成員函式也不能在函式中呼叫其他非const 的函式。______________________________________________________________________________

補充:

以下面的例子為例進行說明:

#include <iostream>;

#include <string>;

using namespace std;

class Student {

        string name;

        int score;

public:

    Student ( ) { } 

    Student ( const string& nm, int sc = 0 )  : name( nm ), score( sc ) { }

    void set_student( const string& nm, int sc = 0 )   // 後面不能有const

        {     name = nm;         score = sc;        }

    const string& get_name() const

       {     return name;   }

   int get_score() const

       {     return score;   }

};

// output student's name and score

void output_student( const Student& student )

{

  cout << student.get_name() << "\t";

  cout << student.get_score() << endl;

}

int main()

{

  Student stu( "Wang", 85 );

  output_student( stu );

}

首先說一點題外話,為什麼 get_name( ) 前面也加 const。如果沒有前後兩個 const 的話,get_name() 返回的是對私有資料成員 name 的引用,所以通過這個引用可以改變私有成員 name 的值,如:

  Student stu( "Wang", 85 );

  stu.get_name() = "Li";      //  引用可以作為左值

即把 name 由原來的 "Wang" 變成了 "Li",而這不是我們希望的發生的。所以在 get_name() 前面加 const 避免這種情況的發生。

那麼,get_name( ) 和 get_score( ) 這兩個後面應該加 const 的成員函式,如果沒有 const 修飾的話可不可以呢?回答是可以!但是這樣做的代價是:const 物件將不能再呼叫這兩個非const成員函數了。如:

const string& get_name( );

int get_score( );        // 這兩個函式都應該設成 const 型

void output_student( const Student& student )

  {

  cout << student.get_name() << "\t";

  cout << student.get_score() << endl;

// 如果 get_name() 和 get_score() 是非const 成員函式,這兩句呼叫都是錯誤的

}

由於引數 student 表示的是一個對const Student 型物件的引用,所以 student 不能呼叫非const 成員函式如 set_student( )。如果 get_name() 和 get_score() 成員函式也變成非const 型,那麼上面的 student.get_name() 和 student.get_score() 的使用就是非法的,這樣就會給我們處理問題造成困難。

因此,我們沒有理由反對使用const,該加const 時就應該加上const,這樣使成員函式除了非const 的物件之外,const 物件也能夠呼叫它。

物件.成員函式

     物件 成員函式 對/錯
1、 const     const     對
2、 const    non-const 錯
3、 non-const const    對
4、 not-const non-const 對



成員函式呼叫成員函式

成員函式 成員函式 對/錯
5、 const     const    對
6、 const non-const   錯
7、 non-const const   對
8、 non-const non-const    對