2016-06-09 81 views
1

我正在閱讀C++初級讀本,而我被困在這個話題上。這是寫的是爲什麼頂層常​​量在複製對象時被忽略?

int i=0; 
const int ci=42; //const is top level. 
const int *p2=&ci; //const is low level. 
const int *const p3=p2; //rightmost const is top level,left one is low level. 
int *p=p3 //error. 
p2=p3 //ok:p2 has the same low level constant qualification as p3. 
int &r=ci; //error: can't bind an ordinary int to const int object 
const int &r2=i; //ok:can bind const int to plain int. 

現在,如果頂層常量在最後聲明中忽略,那麼它應該給一個錯誤,因爲&r2低水平不變資格和我不一樣。爲什麼最後一個staement正確?

+0

我不明白你的問題..你有什麼困惑? – immibis

+1

您的問題的標題似乎與問題的內容無關。我沒有看到任何關於複製對象的問題。 –

+0

我沒有得到處理引用的最後兩條語句。規則即忽略頂級常量在這裏似乎不起作用。 –

回答

4

你在一個問中提出了十億個問題,但我會總結。

  • 這些:

    int &r=ci; //error: can't bind an ordinary int to const int object 
    const int &r2=i; //ok:can bind const int to plain int. 
    

    遵循reference initialization規則。左側需要具有與右側相同或更高的cv資格。

  • 這些:

    const int *p2=&ci; //const is low level. 
    const int *const p3=p2; //rightmost const is top level,left one is low level. 
    int *p=p3 //error. 
    p2=p3 //ok:p2 has the same low level constant qualification as p3. 
    

    遵循qualification conversions規則。基本上他們試圖保持常量的正確性。像p = p3這樣的任務當然不會做。

我認爲你將有一個更容易理解的時間的規則,如果你爲他們顯然沒有幫助您瞭解這裏發生了什麼掉落「頂級」和「低級別」 const東西。

0

在通過const聲明工作時,您向後看。不幸的是,它有一個例外:由於歷史原因允許使用const int,但它意味着與int const相同。

下面,const「回顧」到int因此p指向一個不能更改的int。

int const * p; 

而在這裏,在const「回顧」的int *所以p不允許指向任何東西,但它指向什麼,現在可以通過p改變。

int i = 5; int j = 5; 
int * const p = &i; 
*p = 6;  // ok, you can still modify `i` through `p` 
p = &j;  // error because you can't change what `p` points at 

而這裏,p是const int指針。 p不允許更改,它指向的內容不能更改。

int i = 5; int j = 5 
int const * const p = &i; 
*p = 6;  // error, promised not to makes changes through `p` 
p = &j;  // error `p` is stuck to `i` 

當將一件事分配給另一件事時,規則是承諾不能被破壞。 int const是承諾int永遠不會改變。如果你試試這個:

int const i = 5; 
int * p = &i;  // error 

和編譯器讓你做到這一點,那麼您需要能夠打破i絕不會做改變的諾言這個

*p = 6; 

現在i將被改變從5到6,打破了i永不改變的承諾。

沒關係,因爲你沒有違反任何承諾。在這種情況下,你只能保證不會修改i當你通過指針p

int i = 5; 
int const * p = &i; 
*p = 6;    // error, because we promised not to change `i` through `p` 
i = 6;    // ok, because `i` itself is not const 

const訪問它是重要的,因爲內置的安全檢查。如果您聲明爲const的內容發生更改,編譯器會給您一個錯誤。您可以將類的方法聲明爲const,這是承諾該類中的數據不會被該方法更改。很容易忘記並稍後修改該方法來更改類中的某些內容,但編譯器會提醒您。

這對優化也很重要。如果編譯器知道某事是const它可以做出很多簡化的假設來加速代碼。