天天看點

c++深入了解const以及相關聯的引用知識

/*
時間: 2018/11/12
書籍: c++primer 第五版 c++11标準
*/
           
const的分類
const分為兩種, 一種是底層的const, 一種為頂層的const
  1. 底層const

    底層的const表示指向是常量, 指針本身是變量或者變量

  2. 頂層const

    頂層const表示指針本身是常量, 指向為變量或者常量

const的指派含義
//省略頭檔案以及命名空間

int a[10] = {0};

int* c1 = a;  //可以通過c1改變數組的值, c1也可以指向其餘數組
int* const c2 = a;//必須初始化, c2本身是一個常量, 隻能指向a數組, 初始化就不能改變, 但是可以通過c2改變數組的值
const int* c3 = a;//無所謂初始化, 不能通過c3改變數組的值, 但是c3本身是一個變量, 可以指向其餘的數組

//上述可得, c2就是頂層const, c3就是底層const

           
/*
時間: 2018/11/14
書籍: c++primer 第五版 c++11标準
P256
*/
           

在書籍的構造函數處, 關于初始化

const

資料成員的方法的時候總結下列幾點

1. 如果成員是`const` , 引用, 或者屬于某種未提供預設構造函數的類型, 我們必須通過構造函數初始化清單來為這些成員指派
2. 構造函數的初始化應該和定義順序一緻, 并且避免使用用一個資料成員去初始化另一個資料成員
           

補充以前對于const以及指針引用的錯誤了解

錯誤了解
1. 不能對常量進行引用 
 	以前了解為常量例如 20 40 等數值的引用, 以前的想法覺得肯定是錯誤的, 在書的P55面有詳細的解釋,如下:
 	常量引用是對const的引用
 	第一種以前的證明如下
 	#include <iostream>
	using namespace std;
	int main()
	{
		int &a = 2;	
		return 0;
	}
	在centos上的結果報錯内容如下
	1.cpp: In function ‘int main()’:
	1.cpp:7: error: invalid initialization of non-const reference of type ‘int&’ from a temporary of type ‘int’

2. 引用時兩邊對象的類型必須保持一緻
  	#include <iostream>
	using namespace std;
	int main()
	{
		double a = 22.0;
		int &b = a;
	}
	[[email protected] Test]# g++ 1.cpp
	1.cpp: In function ‘int main()’:
	1.cpp:8: error: invalid initialization of reference of type ‘int&’ from expression of type ‘double’

 		   C++程式員經常把對const的引用簡稱為"常量引用", 嚴格的來說并不存在常量引用, 因為引用不是一個對象, 
 		所有我們沒法讓引用本身恒定不變.
 			事實上, 由于C++語言并不允許随便改變引用所綁定的對象, 是以從這層意義上了解所有的引用都算是常量
 			引用的對象是常量還是非常量可以決定于其所能參與的操作, 卻無論如何都不會影響到對象和引用本身的
 			綁定關系特指出兩個特殊情況
 		第一種情況: 初始化常量引用時允許用任意表達式作為初始值, 隻要該表達式的值能夠被轉換為引用類型即可,
 				   尤其允許為一個常量引用綁定一個表達式and對象and字段例如:
 #include <iostream>
using namespace std;
int main()
{
        double a = 22.0;
        const int &b = a; //編譯時 内部發生轉換,建立一個中間變量來把22.0轉換為int
          /* 
          		const int temp = a;
          		const int &b = temp; 
          */
        const int &c = 2; //常量引用
        const int &d = c * 2;//常量引用


        return 0;
}
接下來深入探讨一下如果當b不是常量的時候會發生什麼事情, 這個時候b如果還能引用到a會發生什麼事情呢, 我們知道編譯器
會有這個轉換的過程, 那麼其實b引用的就是這個中間變量, 就算想通過指派給b來改變a的值也會無法完成, 是以我們得出結論
隻有加上const, 因為加上const以後我們無法改變這個引用的值,也就無法通過複制來改變綁定對象的值
由此我自己又産生一個疑問, 既然時常量那麼無法改變, 那我們改變對象的值會不會對這個常量引用的值造成影響呢?
#include <iostream>

using namespace std;

int main()
{
        int i = 2;
        int &b = i;
        const int &c = i;
        b = 21;
        i = 15;
        cout << c << endl;
        return 0;
}
結果出乎意料, 輸出c的值居然時15, 是以我們得出結論如下
當為常量引用的時候如果我們改變對象的值依然會對常量引用的值産生改變. 但是我們無法通過改變引用的值來改變對象, 理由就像
我們前面說的, 此時常量引用綁定的是編譯器産生的中間變量
           

繼續閱讀