1. 程式人生 > >c++ const的使用

c++ const的使用

情況 特征 std 由於 nat 2個 關鍵字 stc 底層const

const是用來聲明一個常量的,當你不想讓一個值被改變時就用const,
const int max && int const max 是沒有區別的,都可以。
不涉及到指針const很好理解。


涉及到指針的情況:
conat int b=100; 頂層const
int const c=11; 頂層const

const int *a=&b; 底層const
[1] const控制(指針 * )*a不能進行賦值操作 *a=3(錯誤)但可以修改a的存儲的地址 a=&c

int const *a=&b; 底層const

[2] const控制(指針 * )*a不能進行賦值操作 *a=3(錯誤)但可以修改a的存儲的地址 a=&c

int *const a=&b; 頂層const
[3] const控制(變量)a,不能進行賦值操作 a=3,a++(錯誤)但可以修改*a保存b的值 *a=10

const int *const a =&b; 底層和頂層const
[4]從右往左看const,右邊的const 控制了a ,左邊的 const控制*a,所以這裏的2個const 不能改變本身,也不能改變所保存的地址。

const初始化
const的特點:
● 用const加以限定的變量,無法改變。
● 由於const對象定義之後就無法改變,所以必須對其進行初始化。
● const對象的常量特征僅在嘗試改變它的時候表現出來,其他時候和變量無異。
const初始化:
const int bufSize = 512; //bufSize無法再改變
const僅在本文件中有效
const對象通常只在本文件內有效,如果希望其在其他文件中也有效,則需要在其前面加上extern關鍵字。更詳細的做法是,在一個文件中定義const,在其他多個文件中聲明並使用它。
extern const int bufSize = 512;

頂層const和底層const
首先,const是一個限定符,被它修飾的變量的值不能改變。對於一般的變量來說,其實沒有頂層const和底層const的區別,而只有對於指針這類復合類型的基本變量,才有這樣的區別。
如何區分頂層const和底層const?
頂層const表示指針本身是個常量;
底層const表示指針所指向的對象是個常量。
指針如果添加const修飾符時有兩種情況:
● 指向常量的指針:代表不能改變其指向內容的指針。聲明時const可以放在類型名前後都可,拿int類型來說,聲明時:const int和int const 是等價的。聲明指向常量的指針也就是底層const,下面舉一個例子:
int num_a = 1;
int const *p_a = &num_a; //等價於const int *p_a = &num_a,指向const int 類型的指針,是底層const
//*p_a = 2; //錯誤,指向“常量”的指針不能改變所指的對象
註意:指向“常量”的指針不代表它所指向的內容一定是常量,只是代表不能通過解引用符(操作符*)來改變它所指向的內容。
上例中指針p_a指向的內容就不是常量,可以通過賦值語句:num_a=2; 來改變它所指向的內容。
● 常量指針:代表指針本身是常量,聲明時必須初始化,之後它存儲的地址值就不能再改變。聲明時const必須放在指針符號後面,即:const 。聲明常量指針就是頂層const,下面舉一個例子:
int num_b = 2;
int *const p_b = &num_b; //指向int類型的const指針,是頂層const
//p_b = &num_a; //錯誤,常量指針不能改變存儲的地址值
其實頂層const和底層const很簡單,一個指針本身添加const限定符就是頂層const,而指針所指的對象添加const限定符就是底層const。
區分頂層const和底層const的作用
為啥非要區分頂層const和底層const呢,根據C++primer的解釋,區分後有兩個作用。
1 執行對象拷貝時有限制,常量的底層const不能賦值給非常量的底層const。也就是說,你只要能正確區分頂層const和底層const,你就能避免這樣的賦值錯誤。下面舉一個例子:
int num_c = 3;
const int *p_c = &num_c; //指向const int的指針,是底層指針
//int *p_d = p_c; //錯誤,不能將底層const指針賦值給非頂層const指針
const int *p_d = p_c; //正確,都是指向const int的指針
2 使用命名的強制類型轉換函數const_cast時,需要能夠分辨底層const和頂層const,因為const_cast只能改變運算對象的底層const。下面舉一個例子:
int num_e = 4;
const int *p_e = &num_e;
//*p_e = 5; //錯誤,不能改變底層const指針指向的內容
int *p_f = const_cast<int *>(p_e); //正確,const_cast可以改變運算對象的底層const。但是使用時一定要知道num_e不是const的類型。
*p_f = 5; //正確,非頂層const指針可以改變指向的內容
cout << num_e; //輸出5
3練習
說了這麽多,應該練習一下,const int constconst* pppi 是頂層const還是底層const?
答案當然是底層const,因為int前面const限定符,而最後一個*後面沒有const限定符。看最後一個例子:
const int a = 1; //a是頂層const
//int * pi = &a; //錯誤,&a是底層const,不能賦值給非底層const
const int * pi = &a; //正確,&a是底層const,可以賦值給底層const
const int *const *const ppi = &pi //即是底層const,也是頂層const
const int *const *const *pppi = &ppi; //底層const
指針和const限定符(另一版本理解方法)
● 指向const對象的指針
● const指針
● 指向const對象的const指針
const double *p;// 指向const double類型的指針
double *const p = &pi; //指向double對象的const指針
const double *const p = &pi;//指向const對象的const指針
下面看幾個例子:
指向const對象的指針
#include<iostream>
using namespace std;
int main()
{
  double a = 1.2;
  double *p = &a; //p是指向變量a的指針

  const double pi = 3.14;
  //p = &pi;//錯,要想指向一個const對象,必須用指向const對象的指針
  const double *cptr = &pi; //const double類型的指針
  //*cptr = 1.5; //錯,指向const對象的指針只能指向const對象,因而不能修改其值

  system("pause");
}
const指針
指向const對象的const指針
#include<iostream>
using namespace std;
int main()
{
  double a = 1.2;
  double *p = &a; //p是指向變量a的指針

  const double pi = 3.14;
  //p = &pi;//錯,要想指向一個const對象,必須用指向const對象的指針
  const double *cptr = &pi;
  cptr = &a; //指向const對象的指針也能指向非const對象
  //*cptr = 1.5; //但是不能通過指針對其進行修改

  int errNum = 0;
  int *const curErr = &errNum; //指向int對象的const指針,必須進行初始化,而且該const指針不能再指向其他對象

  const double *const pi_ptr = &pi; //指向const double對象的const指針
  //不可以再指向其他的對象,而且也不可以通過指針修改對象的值

  system("pause");
}
const寫在左邊也行,寫在右邊也行。
const string str1;
string const str2;
上面的兩種寫法都是對的。

c++ const的使用