0

我使用 WTL CString 类。这个类有一个重载运算符:

operator LPCTSTR() const
{
    return m_pchData;
}

所以我这样使用它:

CString sText = _T("I like CString!");
TRACE("%s", sText);

我得到了:

Output: I like CStrings!

但是在我添加了一些自己特定的转换方法和运算符之后:

operator LPWSTR() const
{
    return ConvertStringToWide();
}

operator LPSTR() const
{
    return ConvertStringToAnsi();
}

现在我得到而不是:

Output: I like CStrings!

这:

Output: &%?....

在进行了一些测试后,我发现 CString 现在不是调用 operator LPCTSTR() 并返回 m_pchData 它返回类的 this 指针!所以我总是得到指向类而不是 m_pchData 的指针。

所以我的问题是:如何告诉 CString 类默认使用运算符 LPCTSTR() 而不返回 this 指针?

4

1 回答 1

0

通过将类实例传递给可变参数函数,您的程序表现出未定义的行为。

意识到该程序从未operator LPTSTR在您添加之前或之后调用过。编译器不知道“%s”是什么意思(函数实现知道)。它只是将实例转储到堆栈上,该函数看到 %s,从堆栈中抓取四个字节并认为它们是一个TCHAR*指针。

您的程序过去或多或少是偶然工作的:CString类恰好包含一个 TCHAR* 指针作为其唯一成员,因此它的内存表示与原始指针无法区分。嗯,实际上,这不是偶然的:这个类被精心设计成这样,正是因为 MSVC 程序员习惯于将CString实例传递给 printf 等;有很多代码在做(非法)你正在做的事情。

无论如何,我有根据的猜测是,您的问题不是在您向您的版本CString(无论是重载运算符还是其他)添加更多方法时开始的,而是在您添加更多非静态数据成员时开始,从而破坏了精心构建的烟雾和镜子系统。

于 2013-07-14T00:28:15.903 回答