1. 程式人生 > >從const int *p、int* const p到this指標的const屬性分析

從const int *p、int* const p到this指標的const屬性分析

一、指標和const

總體來說:如果關鍵字const出現在星號(*)左邊,表示被指物是常量;如果出現在星號右邊,表示指標自身是常量;如果出現在星號兩邊,表示被指物和指標兩者都是常量。

1、const int *p:指向常量的指標(pointer to const)

(1)、指向常量的指標不能修改其所指物件的值

        const int *p:const int 修飾*p,*p是常量,不能再賦值,而p可以賦其他變數的地址,此處const int 與int const位置沒有區別;

       (2)、要存放常量物件的地址,只能使用指向常量的指標;也可以將普通的物件地址賦值給指向常量的指標,但是不能通過指向常量的指標來修改這個普通變數的值。

<span style="font-family:Microsoft YaHei;">#include <iostream>
using namespace std;

int main()
{
	//(1)指向常量的指標不能修改其所指物件的值;
	int i = 10;
	int j = 20;
	const int *p;
	int const *q;
	/*const int 修飾*p,*p是常量,不能再賦值,而p可以賦其他變數的地址 */
	p = &i;
	//*p = j;  //錯誤 ,不能修改指向常量的指標的值(*p) 
	p = &j;    //正確 ,可以向指向常量的指標賦其他地址(p)
	cout<<*p<<endl;
	/*int 與 const 的位置沒有關係*/
	q = &i;
	q = &j;
	cout<<*q<<endl;
	//2、要存放常量物件的地址,只能使用指向常量的指標;
	const double cpi = 3.14;    //pi是一個常量 
	//double *ptr = &cpi;       //錯誤:ptr是一個普通指標
	const double *cptr = &cpi;  //正確
	//*cptr = 42.1;             //錯誤:*cptr是常量
	cout<<*cptr<<endl;
	double pi = 3.1415;         //pi是普通變數
	const double *pt = π     //正確,但是同樣不能通過*p修改pi的值 	
	return 0; 
}</span>

2、int* const p:常量指標(const pointer)

(1)、指標本身定義為常量,常量指標必須初始化;

(2)、不能直接將const int*型別指標,賦值給int* 型別的指標;

<span style="font-family:Microsoft YaHei;">#include <iostream>
using namespace std;
int main()
{
	//(1)\ 
	int i = 10;
	int j = 20;
	//const 修飾p,不變的是指標本身的值,而非指向的那個值  
	//int* const p;       //錯誤資訊:uninitialized const 'p'
	int* const p = &i;  //正確初始化 
	//p = &j;             //錯誤 ,常量指標必須初始化,而且初始化後(存放在指標中的地址)不能再改變 
	*p = j;             //正確,可以修改指標指向物件的值,但是不能改變指標指向的地址  
	cout<<*p<<endl;//輸出為j的值20 
	
	//(2)\
	const int b = 200;
	//&b為const int*型別指標,而ptr為int* 型別的指標,不能直接賦值 
	//int* const ptr  = &b;      //錯誤:直接將const int* 型別的指標賦值給int *型別
	int* const ptr1 = (int *)&b; //正確:通過強制轉換初始化 
	cout<<*ptr1<<endl;           //輸出為b的值200 
	
	return 0; 
}</span>

二、this指標與const

        在C++的類成員函式中,在成員函式的開始執行前會構造一個 this 指標。預設情況下,this的型別是指向類型別非常量的常量指標,即Test *const this(Test為類名),與前面2中討論的常量指標類似。此時,我們的常量物件(const Test*)不能直接訪問普通的成員函式(Test*),因此需要將普通成員函式宣告成常量成員函式(this宣告成const Test* const this)。

<span style="font-family:Microsoft YaHei;">#include <iostream>
using namespace std;
class test
{
public:
	test():data(1)
	{};
	//普通成員函式 
	void print()
	{
		//使用this指標輸出成員變數 
		cout<<this->data<<endl;//輸出1 
		//this的型別位Test* const this
		//類似與上面的常量指標,可以改變其指向變數的值,
		//但是不能改變this指向的地址 
		this->data = 20;        //正確:常量指標可以改變*this的值;
		cout<<this->data<<endl; //輸出20; 
		const test t;
		//this = (Test*) &t;    //錯誤,不能修改常量指標所指的地址 
	}
	//常量成員函式 
	//通過常量成員函式,將this宣告成const Test* const。
	void show() const
	{
		cout<<this->data<<endl;
	}
private:
	int data;
};
int main()
{
	test t;
	t.print();       //正確:呼叫普通的成員函式,列印物件的私有成員變數 
	t.show();        //正確:普通物件呼叫常量成員函式 
	const test ct;
	//ct.print();    //錯誤:使用了const test* const this型別的指標呼叫了test* this,類似const int *與 int *
	ct.show();       //正確,通過常量成員函式,將this宣告成const Test* const。 
	
	return 0;
}</span>