2013-02-12 76 views
0

我編譯這個片段鏗鏘++( 「蘋果鐺版本4.1(標籤/(基於LLVM 3.1svn蘋果/鐺-421.11.66))」),雖然也GCC它只是罰款:爲什麼這讓我得到一個非const指針指向一個const對象的字段?

#include <iostream> 

struct Foo 
{ 
    typedef unsigned char MemoryPage[0x1000]; 

    MemoryPage* pages; 

    Foo() { pages = new MemoryPage[16]; } 
    ~Foo() { delete[] pages; } 

    unsigned char* PointerToOffset(unsigned offset) const 
    { 
     return pages[offset >> 12] + (offset & 0xfff); 
    } 
}; 

它編譯得很好。我很驚訝,因爲PointerToOffset具有const限定符,但返回值是非constunsigned char指針。

我還可以保證它返回的pages存儲器範圍內,這意味着我得到一個實際非const指針實際const對象數據內的值,而不是一個懸空參考目標陣列的最終拷貝。

結果似乎是一個常量不正確的方法。什麼使它合法?

+0

這與const * const是不一樣的。 – 2013-02-12 06:10:23

回答

3

用最簡單的話變量,

MemoryPage* pages; 

會變成:

MemoryPage* const pages; // and not `const MemoryPage*` 
//   ^^^^^ 

const函數中:PointerToOffset()

const的含義是類變量不能被修改。要使pages成爲不可變實體,const必須應用於pages本身,而不是其指向的內容。
這就是編譯器沒有錯誤的原因。

爲了便於理解,請簡單地嘗試聲明pagesconst MemoryPage*,然後您會注意到即使在非const函數中編譯器也會發出錯誤。

+0

爲什麼它變成'MemoryPage * const'而不是'const MemoryPage *'?它在我看來並不是它應該做的。如果它是一個「char」指針,畢竟它將成爲一個「const char *」。 – zneak 2013-02-12 06:07:55

+0

@zneak,爲您的問題添加了解釋。如果你想修改'pages',那麼你可以這樣寫:'pages = x;'而不是'* pages = x;'。在'const'函數中,類成員變量不應該被修改。所以'pages'變成'T * const'而不是'const T *'。 – iammilind 2013-02-12 06:12:10

+0

我住過一個謊言! d: – zneak 2013-02-12 06:18:17

相關問題