c++ - 用 CString 替换 LPCTSTR 是否安全?

函数的一个参数需要一个LPCTSTR类型的变量;如果我们传递一个 CString 类型的变量呢?在这种情况下它安全吗?或者有什么我们应该注意的吗?

例如这个函数:

Add(new CAToolbar, _T("Command Toolbar"), xtpBarTop);

这里我想用CString str;替换_T("Command Toolbar")(LPCTSTR类型)。像这样:

Add(new CAToolbar, str , xtpBarTop);

安全吗?

最佳答案

Is it safe or is there anything that we should look at in this case?

一般(见下面的注释),是的,它是安全的。 CString 类有一个 operator LPCTSTR(),它将字符串的内容作为 C 风格、以 nul 结尾的 charwchar_t 数组(嗯,指向其第一个元素的指针),取决于“字符集”选项的当前编译器设置(即是否 UNICODE 和/或 _UNICODE 已定义)。因此,返回的类型将(或应该)匹配所需的const char* vs const wchar_t* 指针类型为您的功能参数。 (请注意,对于 const 限定的函数参数,这是安全的。

在“过去”,我使用的一些编译器在执行此操作时会提示“隐式”转换,因此我使用了 CString::GetString() 函数,而不是.然而,它们完全做同样的事情。来自“atlsimpstr.h” header :

template< typename BaseType , bool t_bMFCDLL = false>
class CSimpleStringT
{
//...
    operator PCXSTR() const throw()
    {
        return( m_pszData );
    }
//...
    PCXSTR GetString() const throw()
    {
        return( m_pszData );
    }
//...

重要说明:使用此“隐式转换”安全的一种情况是对于采用 variadic arguments 的函数。 ,例如 printfCString 本身的 .Format() 成员;在这种情况下,编译器会(正确地)提示类对象的不可移植使用。采取以下代码:

#include <afx.h>

int main()
{
    CString param = _T("param");
    CString text;
    text.Format(_T("Param is %s"), param);

    return 0;
}

clang-cl 编译器给出了这个错误:

error : cannot pass object of non-trivial type 'CString' (aka 'CStringT<wchar_t, StrTraitMFC_DLL<wchar_t>>') through variadic method; call will abort at runtime [-Wnon-pod-varargs]

甚至 MSVC 本身也给出:

warning C4840: non-portable use of class 'ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>' as an argument to a variadic function

在这种情况下,您可以使用前面提到的.GetString() 函数,或者显式 进行转换:

    text.Format(_T("Param is %s"), param.operator LPCTSTR());
// or ...
    text.Format(_T("Param is %s"), static_cast<LPCTSTR>(param));

https://stackoverflow.com/questions/72088409/

相关文章:

awk - 用键分隔行并存储在不同的文件中

r - 在嵌套列表中从第一个列表中选择第一个元素,从第二个列表中选择第二个元素,依此类推

python - 为什么有些功能pass了

r - 使用 Slice 或 Stringr 更改 R 中字符串向量中特定字符串的位置?

haskell - 为什么不是 (20 >) 。长度 。取 10 === const True

nuxt.js - 如何在 Nuxt 3 中间件获取当前域?

ios - Xcode 构建失败 : Requested but did not find exte

r - 根据特定列中的数据框条目添加新列的最快方法是什么

python - 如何找到具有最少步数的元素

module - 是否有一种简洁/内联的方式来创建 Set 值而不显式命名它们的类型?