C++ 筆記:引用、指標和 const 限定符
阿新 • • 發佈:2018-12-12
引用
- 引用必須初始化,也就是說,引用從“出生”開始就必須繫結至另一個物件,且必須“從一而終”
- 引用必須繫結至物件,而不能繫結至字面值或表示式計算結果
- 引用的型別要和其繫結的物件嚴格匹配,但有兩個例外情況:
- 可以將常量引用繫結至非常量、表示式或字面值,只要型別匹配
- ================================================
- 引用本身不是物件,因此不存在對引用的引用
double value = 3.14159;
double &ref_value = value;
double &ref1; // error: 'ref1' declared as reference but not initialized
double &ref2 = 3.14159; // error: cannot bind non-const lvalue reference of type
// 'double&' to an rvalue of type 'double'
double &ref3 = 3.14159 * value; // error: cannot bind non-const lvalue reference of type
// 'double&' to an rvalue of type 'double'
int ival = 1;
double &iref = ival; // error: invalid initialization of reference of type
// 'double&' from expression of type 'int'
double &ref_ref_value = ref_value;
指標
- 指標的型別要和其指向的物件嚴格匹配,但有兩個例外情況:
- 可以將指向常量的指標指向非常量,只要型別匹配
- ========================================
- 引用不是物件,因此不存在指向引用的指標
- 使用字面值
nullptr
來獲得空指標 - 建議初始化所有的指標,並儘量等定義了物件之後再定義指向它的指標。如果實在不清楚指標應該指向何處,就把它初始化為
nullptr
或者0
const
限定符
const
物件必須初始化, 且一旦建立後其值不能改變,因此只能在const
物件上執行不改變其內容的操作- 如果利用一個物件去初始化另外一個物件,則它們是不是
const
無關緊要
const int buffer_size = 1024;
int buffer1 = buffer_size;
const int buffer2 = buffer1;
const double value2; // error: uninitialized const 'value2'
- 預設情況下,
const
物件被設定為僅在檔案內有效。當多個檔案中出現了同名的const
變數時,等同於在不同檔案中分別定義了獨立的變數。如果想在多個檔案之間共享const
物件,必須在變數的宣告和定義之前都新增extern
關鍵字
// file1.cpp
extern const int buffer_size = 512;
// file2.cpp
extern const int buffer_size;
對 const
的引用
- 可以將常量引用繫結至常量,兩者均不可修改:
const int buffer_size = 1024;
const int &ref_buffer_size = buffer_size;
- 也可以將常量引用繫結至非常量,只要型別匹配。但是不允許通過引用改變該非常量的值,儘管該非常量的值可以通過其他方式改變:
double value = 3.14159;
const double &ref_value = value;
value = 1.0; // ref_value = 1.0
ref_value = 3.0; // error: assignment of read-only reference 'ref_value'
- 還可以將常量引用繫結至型別匹配的表示式或者字面值:
const int &ref1 = 1024;
const int &ref2 = ref1 * 2;
- 不允許將非常量引用繫結至常量物件,因為這將存在通過非常量引用修改常量物件的風險:
const int buffer_size = 1024;
int &ref_buffer_size = buffer_size; // error: invalid initialization of reference of
// type 'int&' from expression of type 'const int'
指向 const
的指標
const double value = 3.14159;
const double *p_value = &value;
double *p_value2 = &value; // error: invalid conversion from 'const double*' to 'double*'
value
為常量,因此不能通過指標改變它的值,所以不允許將普通指標指向常量- 指向
const
的指標可以指向非常量,但是不允許通過該指標改變其所指物件的值:
double sqrt2 = 1.414;
const double *p_sqrt2 = &sqrt2;
*p_sqrt2 = 1.732; // error: assignment of read-only location '* p_sqrt2'
// 儘管 sqrt2 是非常量,但是 p_sqrt2 單方面認為 sqrt2 不可改變
// 另一方面 sqrt2 可以通過其他方面改變
指向非常量的 const
指標
- 指標本身是
const
,因此其值不能改變,也就是說,不能將const
指標指向別的物件,因此const
指標必須初始化
double value = 3.14159;
double *const p_value = &value;
value = 1.0; // value 為非常量,可以被修改
*p_value = 2.0; // value = 2.0,p_value 不是指向 const 的指標,可以用來改變 value 的值
double sqrt2 = 1.414;
p_value = &sqrt2; // error: assignment of read-only variable 'p_value'
- 儘管指標本身是
const
,但其指向的值是非常量時,仍然可以通過該指標修改其指向的物件,因為這並不改變指標本身的值
指向 const
的 const
指標
const double value = 3.14159;
const double *const p_value = &value;
- 此時指標及其指向的值都不可改變
頂層 const
- 頂層
const
:指標本身是const
- 底層
const
:指標所指的物件是const
,或引用所繫結的物件是const
- 當執行物件的拷貝操作時,拷入和拷出的物件必須具有相同的底層
const
資格