为什么在使用可变参数函数时必须将CString强制转换为LPCSTR?

时间:2013-01-16 11:29:18

标签: c++ mfc

根据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演员),我从来没有遇到过问题。

我在这里错过了什么吗?

4 个答案:

答案 0 :(得分:3)

因为在指定printf()

的参数时没有完成强制转换,因此在Format函数内部没有执行强制转换

如果你写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参数,它会破坏。