1. 程式人生 > >C++ 筆記:引用、指標和 const 限定符

C++ 筆記:引用、指標和 const 限定符

引用

  • 引用必須初始化,也就是說,引用從“出生”開始就必須繫結至另一個物件,且必須“從一而終”
  • 引用必須繫結至物件,而不能繫結至字面值或表示式計算結果
  • 引用的型別要和其繫結的物件嚴格匹配,但有兩個例外情況:
    • 可以將常量引用繫結至非常量、表示式或字面值,只要型別匹配
    • ================================================
  • 引用本身不是物件,因此不存在對引用的引用
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,但其指向的值是非常量時,仍然可以通過該指標修改其指向的物件,因為這並不改變指標本身的值

指向 constconst 指標

const double value = 3.14159const double *const p_value = &value;
  • 此時指標及其指向的值都不可改變

頂層 const

  • 頂層 const:指標本身是 const
  • 底層 const:指標所指的物件是 const,或引用所繫結的物件是 const
  • 當執行物件的拷貝操作時,拷入和拷出的物件必須具有相同的底層 const 資格