为什么我需要这个 CString 类型转换
Why do I need this CString type cast?
我已经将字符串移动到资源中,幸运的是我有 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 才能完成这项工作呢?
你的IDS_MY_STRING
并不是一个指向字符串的指针。它是一个整数。(如果它是一个字符串指针,则从一开始就不需要LPCTSTR
强制转换。 CString
知道如何从整型资源 ID 加载资源字符串。
MessageBox
不需要;它需要一个真正的字符指针,CString
隐式提供。
真正的问题(或者至少是答案中有趣的部分)不是关于第二个如何失败,而是关于第一个如何工作。
第一个工作是因为 CString 的构造函数采用 LPCSTR 实际上查看值以确定它是否真的是指向字符串的指针,还是字符串资源的标识符。在后一种情况下,它会自动加载字符串资源并创建具有相同内容的 CString。IOW,您已经获得了从字符串标识符到 CString 的隐式转换。
CString 还支持隐式转换为
LPCSTR/LPCSTR/LPCWSTR。但是,C++只会执行一个用户定义的隐式转换,以从传递的任何类型获取表达式所需的任何类型。在这种情况下,要从字符串 ID 获取到LPCTSTR
,您需要两个 - 一个从字符串 ID 到 CString
,另一个从CString
到LPCTSTR
。编译器不会自动为您执行此操作。
因此,要从字符串 ID 获取到LPCTSTR
,需要显式地从字符串 ID 转换为 CString
,这使用 CString
的构造函数,该构造函数需要LPCTSTR
。因此,您将字符串 ID 强制转换为 LPCTSTR
,并从该 转换为 CString
,这将创建一个CString
。然后编译器会自动从CString
转换为(真正的)LPCTSTR。
其他人已经解释了类型转换等的细节。
此外,为了简化代码,您可能需要#define
一个方便的宏,如下所示:
#define _S(id) (CString(LPCTSTR(id)))
然后将其与MessageBox
一起使用(或用于其他LPCTSTR
参数):
MessageBox( hWnd, _S(IDS_MY_STRING), _S(IDS_TITLE), MB_RETRYCANCEL );
MessageBox
没有占用资源 ID 的重载,但您可以改用AfxMessageBox
。
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- C++中的双指针类型转换
- 逐位操作的隐式类型转换
- 模板中的类型转换
- 在 C++(和 C)中进行类型转换时明显不一致
- 字符类型转换不兼容
- 将复杂的非基元C++数据类型转换为 Erlang/Elixir 格式,以使用 NIF 导出方法
- C++:用户定义的显式类型转换函数错误
- 将类指针类型转换为键时出错
- 通过引用传递参数时C++类型转换
- 在 C++ 中将一个模板类型的对象类型转换为另一个模板类型
- C++显式类型转换(C 样式强制转换)的强制表示法和static_cast的多种解释
- C++无效的函数类型转换
- 在将派生类指针类型转换为派生类指针后,从基类指针调用派生类函数
- 如何将Windows产品类型转换为名称?
- 为什么我需要这个 CString 类型转换
- 为什么将CString类型转换为wchar_t*会产生一个临时副本?如果我们使用其他类型而不是CString呢?
- 如何将LONG类型强制转换为CString类型
- 如何将CEdit类型的数据转换为CString类型的数据,以及如何在消息框中显示