從const int *p、int* const p到this指標的const屬性分析
阿新 • • 發佈:2019-01-05
一、指標和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>