程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 刨根問底系列之C++ const 挖掘

刨根問底系列之C++ const 挖掘

編輯:C++入門知識

一、 const的作用:

     1、限定const指定的值的修改

          ex1.1:

          const int a = 2;

          //a = 3;  error: assignment of read-only variable

     就如C語言裡宏一樣,a會被放到符號列表裡,不過a是內部鏈接的(內部鏈接是指只在當前文件內是可見的)。當不取a的地址的時候,系統不會給a分配內存,取a地址的時候就會給a分配地址,但改變a指向的內容並不能改變a的值,因為a已經被編譯成為符號了。改變a內存所指內容是沒有任何結果的。

          ex1.2:

[cpp] 
#include <iostream> 
using namespace std; 
int main() { 
    const int ci = 2; 
    cout<<"the addr of ci is:"<<(&ci)<<endl; 
    int *p = const_cast<int*>(&ci); 
    cout<<"the addr of p is:"<<p<<endl; 
    *p = 5; 
    cout<<"the value of ci is:"<<ci<<endl; 
    cout<<"the value of p is:"<<(*p)<<endl; 
    return 0; 

          輸出結果為:

         

     2、限定函數返回值的修改,限定函數內容的修改

          函數返回值加上const,防止賦值運算,member function加上const 限定,防止對象member data修改。

          ex1.3:

[cpp] 
#include <iostream> 
using namespace std; 
class Test{ 
    public: 
        Test(); 
        ~Test(); 
        Test& GetTest() { 
            return *this; 
        } 
        const Test& GetConstTest(){ 
            return *this; 
        } 
 
        const Test& operator=(const Test& other) { 
            this->value_ = other.value_; 
            return *this; 
        } 
 
        int ChangeValue(int value) const { 
            //value_ = value;   error: value_ is read only 
            return value_; 
        } 
    private: 
        int value_; 
}; 
int main() { 
    Test test; 
    test.GetTest() = test; 
    //test.GetConstTest() = test; //error can't assignment to return value 
    return 0; 

 
          在函數member function GetConstTest() 裡返回值是const屬性的,所以不能為返回值賦值。在ChangeValue裡member function 被限定為const 成員函數,所以在內部不能修改member data value_ 的指。

     3、程序的可讀性

          加上const限定,可以很清楚的告訴編譯器和程序員,這個數值不可以修改。同時將函數參數定義為const 引用,這樣和傳遞值的感覺是一樣的,防止程序傳遞整個對象。

     4、程序的效率

          在函數參數的傳遞過程中,變量都是按值拷貝傳遞的,如果是內置類型的話,占用內存空間少,拷貝一下數值無關緊要。但是自定     義類就沒想像的簡單了。在參數傳遞過程中,如果是按值傳遞的話,對象會調用自己的構造函數,並且將整個對象內容拷貝過去,這對於占用內存較多的類還是非常損耗效率的。如果定義為引用或者指針傳遞的話拷貝指針值就可以了。

     5、代替部分宏的職責

          C語言之所以在發明的時候受到了各方程序員的萬般寵愛,很大一部分原因就是C語言裡的宏。宏不僅可以定義全局數據符號,並且還可以用來構造非常精妙的函數。定義常用的變量,常用的函數非常方便。在方便的同時也有很多問題,比如說沒有類型檢查,只是機械的替換,比如說經典的”Max 宏函數“各種錯誤。看下面的例子。

          ex1.4:

[cpp]
#include <iostream> 
using namespace std; 
#define PI 3.14 
#define Log(str) cout<<str<<endl 
#define Max(a, b) a > b ? a : b 
 
int main() { 
    int a = 12; 
    int b = 5; 
    int max = Max(a, b); 
    Log(PI); 
    Log(max); 
    Log("hello, world"); 
    return 0; 

          但是通過C++裡的const就能很好的規避一些問題

          1、類型檢查

          2、名稱沖突,因為宏定義變量是外鏈接的

          3、調試代碼效率問題上,如果在宏變量的地方出錯了,編譯器只是將宏變量代替為值,所以當看到對應的值的時候,會非常奇怪這個值是那裡來的,但是對於const變量可以很清楚的知道是那個變量。

 

二、const的用法

     1、限定內置常量

          限定常量很簡單,在定義const變量的時候必須初始化,初始化的值可以是常量,也可是變量。

          ex2.1:

     2、限定指針和引用

          指針地址是程序運行的時候為變量分配的內存,所以const指針是不需要初始化的。由於const放的位置不同,對應限制的值也不同。通用的方法就是看const和變量的位置。

[cpp] 
int num = 2; 
int other = 3; 
 
// assignment 
const int* ptr1 = &num 
int const* ptr2 = &num 
int *const ptr3 = &num 
const int* const ptr4 = &num 
 
// change value 
ptr1 = &other; 
ptr2 = &other; 
// ptr3 = &other;     // read only error 
// ptr4 = &other;     // read only error 
 
// *ptr1 = other;     // read only error 
// *ptr2 = other;     // read only error 
*ptr3 = other;      
// *ptr4 = other;     // read only error 


     3、限定對象

     const 在限定對象使用要點:

     1、按位限制,對象占用的內存不可改變,將this指針轉為非const指針就可以改變member data。

     2、按邏輯限制,對象中的數據成員限制,在const member function 中值申明為mutable 就可以改變。

     3、const member data 必須在初始化列表裡初始化完。

     4、在class 內部只有char, int, long, float, double可以通過static const 申明的時候賦值。

     ex2.3

[cpp]
#include <iostream> 
using namespace std; 
 
const int MAX_FRIEND = 100; 
class Player{ 
    public: 
        enum { 
            boy = 1, 
            girl = 0 
        }; 
        Player() : user_id_(0), user_sex_(boy){} 
        ~Player(){} 
 
        Player(const Player&); 
        const Player& operator=(const Player&); 
 
        void SetUserId(int user_id); 
        int GetUserId() const; 
 
        void SetGroupId(int group_id) const; 
        int GetGroupId() const; 
 
        void SetUserAge(int user_age) const; 
        int GetUserAge() const; 
 
        void SetUserName(const char* user_name); 
        void PrintPlayerInfo() const; 
 
    private: 
        int user_id_; 
        mutable int group_id_; 
        int user_age_; 
        string user_name_; 
        const char user_sex_; 
        static const int friend_count_ = MAX_FRIEND; 
}; 
 
Player::Player(const Player& player):user_sex_(boy) { 
 

 
const Player& Player::operator=(const Player& other) { 
 

 
void Player::SetUserId(int user_id) { 
    user_id_ = user_id; 

 
int Player::GetUserId() const { 
    return user_id_; 

 
void Player::SetUserAge(int user_age) const { 
    const_cast<Player*>(this)->user_age_ = user_age; 

 
int Player::GetUserAge() const { 
    return user_age_; 

void Player::SetGroupId(int group_id) const { 
    group_id_ = group_id; 

 
int Player::GetGroupId() const { 
    return group_id_; 

 
void Player::SetUserName(const char* user_name) { 
    user_name_ = user_name; 

 
void Player::PrintPlayerInfo() const { 
    cout<<"user id:\t"<<user_id_<<endl; 
    cout<<"user name:\t"<<user_name_<<endl; 
    cout<<"user sex:\t"<<user_sex_<<endl; 
    cout<<"user age:\t"<<user_age_<<endl; 
    cout<<"user group:\t"<<group_id_<<endl; 

int main() { 
    const Player player1; 
    //player1.SetUserId(100001); 
    player1.GetUserId(); 
 
    Player player2; 
 
    player2.SetUserId(100001); 
 
    player2.SetGroupId(100); 
 
    player2.SetUserAge(21); 
 
    player2.SetUserName("Jack"); 
 
    player2.PrintPlayerInfo(); 
    return 0; 

通過例子2.3可以看出const objects只能讀取內存的值,不能改寫內存的值。對於const member function,member data group_id_ 是按邏輯申明的可改變變量。而在SetUserAge(int user_age)函數裡通過強轉this指針,來改變member data。

     文章裡所示程序在gcc version 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.1.00)環境裡編譯通過,全文完。

參考:

c++ 編程思想卷一

effective c++ 第三版

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved