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

Posted

技术标签:

【中文标题】为啥我需要这个 CString 类型转换?【英文标题】:Why do I need this CString type cast?为什么我需要这个 CString 类型转换? 【发布时间】:2012-04-17 20:47:17 【问题描述】:

我已将字符串移动到资源中,幸运的是,我有 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 才能完成这项工作?

【问题讨论】:

【参考方案1】:

您的IDS_MY_STRING 并不是真正的指向字符串的指针。它是一个整数。 (如果它是一个字符串指针,那么您一开始就不需要 LPCTSTR 强制转换。)CString 知道如何从完整的资源 ID 加载资源字符串。

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

【讨论】:

【参考方案2】:

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

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

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

然而,

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

因此,要将字符串 ID 转换为 LPCTSTR,您需要将字符串 ID 显式转换为 CString,它使用 CString 的构造函数,该构造函数采用 LPCTSTR。因此,您将字符串 ID 转换为 LPCTSTR,然后将其转换为 CString,这将创建一个 CString。然后编译器会自动为您从CString 转换为(真正的)`LPCTSTR。

【讨论】:

你的最后一段有点混乱。我想你想说的是我们仍然需要从string IDCString 的转换。比 CString 隐式转换为 LPCTSTR。通过输入(CString) (LPCTSTR),我们正在进行从ID 到CString 的一次转换。 CString((LPCTSTR)IDS_MY_STRING)而不是两个显式转换不是更易读吗? @ChristianAmmer:是的,我可能会那样做。【参考方案3】:

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

此外,为了简化您的代码,您可能需要#define 一个方便的宏,如下所示:

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

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

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

【讨论】:

【参考方案4】:

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

【讨论】:

以上是关于为啥我需要这个 CString 类型转换?的主要内容,如果未能解决你的问题,请参考以下文章

为啥在java 8中转换类型的reduce方法需要一个组合器

如何将 CEdit 类型的数据转换为 CString 类型的数据以及如何在消息框中显示? [复制]

为啥不能将“UIView”类型的值转换为其他视图?

为啥在使用单指针传递给函数时必须对二维数组进行类型转换?

为啥这个转换的结果不是左值?

在 Objective-C 中,为啥在分配给指定类型的变量时需要强制转换?