我已将字符串移至资源中,幸运的是,我有LPCTSTR运算符可以方便地实例化字符串,例如:
CString str( (LPCTSTR) IDS_MY_STRING);
Run Code Online (Sandbox Code Playgroud)
现在我想做类似的类型转换,MessageBox()因此它也从资源加载字符串,所以我这样做:
MessageBox( hWnd, (LPCTSTR) IDS_MY_STRING , _T("Error"), MB_RETRYCANCEL);
Run Code Online (Sandbox Code Playgroud)
但这不起作用,它可以编译但在运行时崩溃。现在以下内容有效:
MessageBox( hWnd, (CString) (LPCTSTR) IDS_MY_STRING , _T("Error"), MB_RETRYCANCEL);
Run Code Online (Sandbox Code Playgroud)
我的问题是,无论如何,MessageBox()它都作为LPCTSTR第二个参数,那么为什么我们必须另外进行从 到 的类型转换LPCTSTR才能CString使其工作?
真正的问题(或者至少是答案中有趣的部分)不是关于第二个如何失败,而是更多关于第一个如何工作。
第一个之所以有效,是因为CString的构造函数LPCTSTR实际上查看该值以确定它是否确实是指向字符串的指针,或者是字符串资源的标识符。在后一种情况下,它会自动加载字符串资源并创建CString具有相同内容的字符串资源。IOW,您正在获得从字符串标识符到CString.
CString还支持隐式转换为LPCTSTR// 。LPCSTRLPCWSTR
然而,C++ 只会执行一次用户定义的隐式转换,以从传递的任何类型转换为表达式所需的任何类型。在本例中,要从字符串 ID 获取到 a LPCTSTR,您需要两个 — 一个从字符串 ID 到CString,另一个从CStringto LPCTSTR。编译器不会自动为你做这件事。
因此,要从字符串 ID 转换为LPCTSTR,您需要显式地从字符串 ID 转换为CString,它使用CString带有LPCTSTR. 因此,您将字符串 ID 转换为LPCTSTR,然后从该转换为CString,这将创建一个CString. 然后编译器会自动为你转换CString为(实数) 。LPCTSTR