2016-07-06 167 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