根据this site:
,有人知道为什么这些代码不正确CString First( "John" );
CString Last( "Doe" );
CString Name;
Name.Format( "%s %s", First, Last ); // Name may be garbage text
Name.Format( "%s %s", (LPCSTR)First, (LPCSTR)Last ); // this is the correct way
CString::Format的Microsoft文档说:
...当您将字符串作为可选参数传递时,必须将其显式转换为LPCTSTR ...
我总是使用“错误”的方式(没有LPCSTR演员),我从来没有遇到过问题。
我在这里错过了什么吗?
答案 0 :(得分:3)
因为在指定printf()
如果你写printf( "%d", a );
,则a
没有进行强制转换,因为printf认为%d
已经告知了a
的数据类型。
为了确保将CString
转换为LPCSTR
即%s
,您需要转换参数,该参数将调用返回CString
的{{1}}的运算符LPCSTR
。在CString的更高版本中,存储字符串,以便在没有强制转换的情况下进行编写时,它仍将作为LPCSTR打印,但确保最好进行强制转换。
或换句话说:当变量函数通过参数时,它使用格式说明符来知道参数的大小,如果格式说明符与参数不匹配则会产生垃圾。由于CString没有格式说明符,因此需要将CString转换为LPCSTR。
顺便说一句,你应该在C ++中使用static_cast<LPCSTR>(First), static_cast<LPCSTR>(Last)
答案 1 :(得分:2)
转换为LPCSTR会调用强制转换运算符operator LPCSTR()
(应为operator const char *()
。
不调用LPCSTR意味着您传递整个CString对象,然后盲目地使用底层结构的前32位或64位作为char指针。
回顾一下:LPCSTR(str)
正在调用一种方法来确保正确的行为,而str
则是盲目的笨拙。
答案 2 :(得分:1)
我认为(对不起,我现在没有MFC可用来检查)只是出于效率原因需要强制转换,以避免MFC必须在参数类型未知(CString被懒惰复制时)必须执行的无用临时副本在修改)。
CString内存分配的技巧是在 this
之前为缓冲区(TCHAR *)以外的一些基本数据保留空间,就像引用计数器一样。
然后当你通过值将CString传递给一个可变函数时,它'看到'缓冲区(一个指针) 强制转换“提取”只是缓冲区,而不调用复制构造函数。
答案 3 :(得分:1)
因为如果使用了子类CString参数,它会破坏。