2016-07-06 165 views
2

爲什麼下面的代碼會被編譯?C++爲什麼const LPSTR與const char *不同?

void foo(const LPSTR str) { 
    str[0] = '\0'; 
} 

void foo(LPCSTR str) { 
    str[0] = '\0'; 
} 

void foo(const char* str) { 
    str[0] = '\0'; 
} 

沒有。

它實際上LPTSTR在我的代碼,以便const版本LPCTSTR ... 所以我可以通過具有類似const LPTSTR提高代碼的可讀性,也必須是LPCTSTRconst TCHAR*

+5

我強烈建議,如果這不是某些Win32 API特定的代碼,那麼在代碼中不要使用Microsoft typedefs,而應使用真實類型(適用於本示例)或自己製作更明智的typedef。 – rubenvb

+0

這是特定於win32,但謝謝你的提示。 – sooqua

+0

但是Win32的具體問題是什麼?如果不是,你仍然應該抽象出這些類型的別名。事實上,如果你只是簡單地這樣做,你會立即看到問題所在。 –

回答

7

typedef從外部修改「封印」類型。 LPSTRchar *,期間。將const添加到(如const LPSTR)將const添加到外部:您將獲得char * const

你想要的是「注入」const(將它應用於指針,而不是指針),這是不可能通過簡單的聲明語法和typedef。所以它必須是LPCSTR,就是爲此而創建的typedef。

+0

不完整的答案。作爲docs和typedef狀態,LPSTR是'_Null_terminated_ char *'的typedef。這意味着在使用中,尤其是在分析工具中,它會自動告訴工具不要將它視爲指向1個或更多字符的指針,而是特別是以空字符結尾的字符串(這是迄今爲止在c/C++中用於char *的最大用法)。這意味着如果你忘記了null,那麼編譯器會告訴你這個字符串是非常好的 - 如果沒有這些信息,編譯器必須看到你把char *看作一個字符串,然後才能抱怨你錯了。然而,我離題了。 –

1

如果你看一看的documentation你會發現LPSTRCHAR *的別名,而CHAR又的char的別名。因此LPSTRchar*的別名。

爲什麼const LPSTR與const char *不同?

const in const char *適用於char。換句話說,它是一個非const指向const對象的指針。

constconst LPSTR適用於LPSTR,正如我們已經發現的,它是char*。因爲LPSTR是一個指針,這使得指針爲常量。它對指針是指向一個const還是非const對象沒有影響。所以,這個類型是char * const


至於爲什麼當strconst char*沒有str[0] = '\0';不能編譯,原因是您不得修改const對象。它編譯爲char * const,因爲你可以修改非const對象。


PS。這個問題存在的事實說明了如何隱藏別名後面的數據指針類型令人困惑。

0
  1. const LPSTR解析爲char* const:只有指針是固定的,你可以修改它的內容。看看它的定義here。所以你的第一個例子編譯
  2. LPCSTR被解析爲const char*,所以你不能修改它的內容。你可以看到它的定義here。所以,你的第二個例子不const char*編譯
  3. 同樣的,你不能修改其內容,所以你的最後一個例子不能編譯
-3

因爲LPCSTR是不一樣的(假設的)CLPSTR