C++primer 4.2 指針和const限定符(3)

簡介

建議(remember)

- 指向const對象的指針(const和非const都可以)

 1. 可以初始化爲const和非const的對象;
 2. 把非const對象的地址賦給指針時,不允許用指針來改變其所指的const的值;
 3. 定義指針時不需要初始化

- 指向非const對象const指針(只能非const對象)

 1. 指針一直指向某一個對象,指針不能被修改;
 2. **定義時必須初始化指針,初始化爲非const的對象,不能初始化爲const對象**;
 3. 因爲指向的是非const對象的const指針,所以我們可以通過指針來改變所指對象的值。
 4. 所指對象值的變化和指針沒有關係

- 指向const對象的const指針(只能const對象)

1. 既不能通過指針來修改所指向的對象的值,也不能修改指針的指向。
2. 必須初始化;
3. 初始化的對象必須也是const類型的

- 關於const 需要記住的

1. 常量是不能被賦值的,const定義的都是常量,且定義一個const對象必須初始化,無論是const變量還是const指針或是const數組;
2. 如果const定義針對的是指針,那麼那個指針就不能再被賦值;
3. 如果定義的是一個整型或是別的類型對象,那麼該對象初始化後也不能再被賦值
4. const位置的不同修飾的也不同,區別const指針和指向const對象的指針的區別;
5. 前者針對指針,所以指針不能變,並不對其所指的對象有限制,對象的值還是可以變的;
6. 後者修飾的是所指的對象,所以對象的值不能變,但是指針可以

疑問:

p112

=======================================================================================================================================

一、指向const對象的指針

  1. 如果指針指向const對象,則不允許用指針來改變其所指的const的值,爲了保證這個特性,要求指向const對象的指針也必須具有const特性;
 const double * cptr 
  //cptr是一個指針,是一個指向 double類型const型對象的指針`
  //因爲const是對指針所指的對象做出的限定,所以定義時不需要對指針cptr進行初始化
  //如果需要的話,允許給cptr重新賦值,使其指向另一個const對象,但不能通過cptr修改其所指對象的值
*cptr=42//這是錯誤的
 //把一個const對象的地址賦給一個普通的、非const對象的指針也會導致編譯出錯
const double pi=3.14;
double *ptr=π  //錯誤,因爲ptr不是const類型指針
const double *cptr=π//可以
//允許把非const對象的地址賦給指向const對象的指針
double dval=3.14;
cptr =&dval;//可以,但是不能通過指針來修改dval的值,可以通過別的方法來

//可以修改const指針所指向的的值
dval =3.14159;
*cptr=3.14159; //錯誤,不可以通過指針來修改const對象的值
double *ptr=&dval; 
*ptr=2.72;//可以,因爲ptr是一個普通指針,所以dval的值改成了2.72
cout<<*cptr<<endl;//輸出2.72

二、指向非const對象的const 指針

  1. const指針,指針本身值不能修改,所以定義時就要初始化
  2. 可以賦值爲非const常量。
  3. 因爲指向的是非const對象的const指針,所以我們可以通過指針來改變所指對象的值。
int errNumb=0;
const int ic=8int *const curErr=&errNumb;//可以,用非const對象賦值指向int型對象的const指針
int *const curErr=&ic;//不可以用const對象給指向int型對象的const指針賦值

curErr =curErr;//錯誤,任何企圖給const指針賦值的行爲都會導致編譯時的錯誤
if(*curErr){
errorHandler();
*curErr=0;// 可以,因爲指針指的不是一個const型對象
}

三、指向const對象的const指針

  1. 既不能通過指針來修改所指向的對象的值,也不能修改指針的指向。
  2. 必須初始化;
  3. 初始化的對象必須也是const類型的
const double pi=3.14159;
const double *const pi_ptr=&pi;
//不能修改指針的指向,也不能修改指針指向的對象的值

四、指針和typedef

//下面的例子請問cstr是什麼類型

typedef string *pstring;
const pstring cstr;


/*因爲const修飾的是pstring的類型,這是一個指針,因此,該聲明語句應該是把cstr定義爲指向string類型對象的const指針,等價於
*/
string *const cstr;
p112

五、理解複雜的const類型的聲明

  1. 閱讀const聲明語句產生的部分問題,源於const限定符既可以放在類型前也可以放在類型後

    1. string const s1;
    2. const string s2;

    2.用typedef寫const類型定義時,const限定符最好加在後面,即離對象更近

string s;
typedef string *pstring;
const pstring cstr1=&s;
pstring const  cstr2=&s;
string *const cstr3=&s;
/*
把const放在類型pstring之後,然後從右向左閱讀該聲明語句就會清楚的知道cstr2是const pstring類型,即指向string對象的const指針
*/

六、課後習題

記住:

 1. 常量是不能被賦值的,const定義的都是常量;
 2. 如果const定義針對的是指針,那麼那個指針就不能再被賦值;
 3. 如果定義的是一個整型或是別的類型對象,那麼該對象初始化後也不能再被賦值
 4. const位置的不同修飾的也不同,區別const指針和指向const對象的指針的區別;
 5. 前者針對指針,所以指針不能變,並不對其所指的對象有限制,對象的值還是可以變的;
 6. 後者修飾的是所指的對象,所以對象的值不能變,但是指針可以
 7. 
//下面這個例子可以驗證自己對概念理解的如何
int i=-1;
const int ic=i; //可以,初始化,用const和非const變量給const變量初始化,但是後面ic的值就不能變了,就是後面const對象不能被賦值了。
const int *pic=&ic;//可以, 定義一個指向const對象的指針,可以用const和非const類型對象初始化

int * const cpi=&ic;//不可以,定義一個指向非const對象的const指針,只能用非const對象進行初始化
const int * const cpic=&ic; //可以

i=ic;//可以用const對象修改非const對象的值,反之則不行
pic=&ic;//可以,修改指針pic的指向,使他指向ic
cpi=pic;//不可以,因爲指針cpi是const型指針
pic=cpic;//可以,指針指向的變化,指針pic指向對象ic
cpic=&ic;//不可以,cpic是常量指針
ic=*cpic;//不可以,ic是const常量,不能被賦值
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章