2010-08-09 116 views
5

在star之前的C++中的const修飾符意味着使用此指針時,指向的值不能更改,而指針本身可以指向其他指針。在下面的const const指針參數的非const指針參數

void justloadme(const int **ptr) 
{ 
    *ptr = new int[5]; 
} 

int main() 
{ 
    int *ptr = NULL; 
    justloadme(&ptr); 
} 

justloadme函數不應該被允許編輯的整數值(如果有的話)由通過PARAM指出,雖然它可以編輯INT *值(因爲該常量不是第一球星後) ,但仍然爲什麼我會在GCC和VC++中都遇到編譯器錯誤?

GCC:錯誤:無效的轉換從int**const int**

VC++:錯誤C2664:從 '詮釋**' 不能轉換參數1至 'const int的**': 'justloadme'。轉換失去限定符

爲什麼說轉換失去了限定符?它是不是獲得const限定符?此外,它是不是類似strlen(const char*)我們通過一個非const char*

+4

http://www.parashift.com/c++-faq-lite/const-correctness.html#faq-18.17 – Anycorn 2010-08-09 07:40:12

回答

8

大多數時候,編譯器是正確的,直覺錯誤。問題是,如果某個任務被允許,你可以打破常量,正確性,在你的程序:

const int constant = 10; 
int *modifier = 0; 
const int ** const_breaker = &modifier; // [*] this is equivalent to your code 

*const_breaker = & constant; // no problem, const_breaker points to 
           // pointer to a constant integer, but... 
           // we are actually doing: modifer = &constant!!! 
*modifier = 5;     // ouch!! we are modifying a constant!!! 

行標有[*]對於那些違規的罪魁禍首,並禁止該特定原因。語言允許添加常量到最後一層,但不是第一次:

int * const * correct = &modifier; // ok, this does not break correctness of the code 
+0

雖然同意爲了不讓這個'const'修改失敗,編譯器會這樣做。但使用'int * const * correct'甚至不允許我執行'* ptr = new int [5];'。我該怎麼辦? – legends2k 2010-08-09 08:09:05

+1

問題很可能在於你想要做的不是你正在寫的東西。你想要做什麼?簽名需要一個'const int **',但是你傳遞一個'int **'並將它作爲'int **'在函數內處理......你真的想在簽名中使用'const'嗎? – 2010-08-09 08:14:50

+1

哦,現在我明白了!我想要做的是概念上的錯誤,所以是的,你是對的。謝謝! – legends2k 2010-08-09 08:18:01