为什么我需要这个CString类型转换?

时间:2012-04-17 20:47:18

标签: c++ mfc

我已将我的字符串移动到资源,幸运的是我有LPCTSTR运算符来方便地实例化字符串:

CString str( (LPCSTR) IDS_MY_STRING);

现在我想用MessageBox()做类似的类型转换,所以它也从资源加载字符串,所以我这样做:

MessageBox( hWnd, (LPCTSTR) IDS_MY_STRING ,"Error", MB_RETRYCANCEL);

但这不起作用,它编译但在运行时崩溃。现在以下工作:

MessageBox( hWnd, (CString) (LPCTSTR) IDS_MY_STRING ,"Error", MB_RETRYCANCEL);

我的问题是MessageBox()无论如何都将LPCTSTR作为第二个参数,为什么我们还要从LPCTSTR到CString进行类型转换以使其工作?

4 个答案:

答案 0 :(得分:3)

你的IDS_MY_STRING实际上并不是指向字符串的指针。这是一个整数。 (如果它是一个字符串指针,你首先不需要LPCTSTR强制转换。)CString知道如何从整体资源ID加载资源字符串。

MessageBox没有;它需要一个真实的字符指针,CString隐式提供。

答案 1 :(得分:3)

真正的问题(或至少是答案的有趣部分)不是关于第二个失败的方式,而是关于第一个如何工作的更多信息。

第一个可行,因为采用LPCSTR的CString构造函数实际上会查看该值,以确定它是否真的是指向字符串的指针,或者是字符串资源的标识符。在后一种情况下,它会自动加载字符串资源并创建具有相同内容的CString。 IOW,你得到了从字符串标识符到CString的隐式转换。

CString还支持隐式转换为LPCSTR / LPCSTR / LPCWSTR。

然而,

C ++只会执行一个用户定义的隐式转换,以从任何类型传递到表达式所需的任何类型。在这种情况下,要从字符串ID获取LPCTSTR,您需要两个 - 一个从字符串ID到CString,另一个从CStringLPCTSTR 。编译器不会自动为您执行此操作。

因此,要从字符串ID到LPCTSTR,您需要显式地从字符串ID转换为CString,它使用CString的构造函数,其中{{1} }}。因此,您将字符串ID转换为LPCTSTR,然后将其转换为LPCTSTR,这会创建CString。然后编译器会自动从CString转换为(实际)`LPCTSTR。

答案 2 :(得分:1)

MessageBox没有使用资源ID的重载,但您可以改为使用AfxMessageBox

答案 3 :(得分:1)

其他人已经解释了类型转换的细节等。

此外,为了简化您的代码,您可能需要#define这样一个方便的宏:

#define _S(id) (CString(LPCTSTR(id))) 

然后将其与MessageBox(或其他LPCTSTR参数一起使用):

MessageBox( hWnd, _S(IDS_MY_STRING), _S(IDS_TITLE), MB_RETRYCANCEL );