2013-07-13 61 views
0

我使用WTL CString類。這個類有一個重載的操作符:運算符的C++重載此

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它返回這個類的指針! 所以我總是得到指向類的指針而不是m_pchData。

所以我的問題是:我如何告訴CString類默認使用運算符LPCTSTR()而不返回這個指針?

+0

您能否爲您的問題創建一個最小且完整的示例?從上面,你正在調用一些宏'TRACE'(它包裝了一些未知的函數,可能涉及C風格的變量),並且你修改了別人的'CString'(你是在你的項目中本地還是全局?)。如果沒有[sscce](http://sscce.org/),我不得不復制你的確切環境來弄清楚發生了什麼。 – Yakk

+0

我的猜測是它是Win32 API代碼。 'CString'是MFC的字符串類,'TRACE'是一個VC/Windows宏。請注意,這只是一個澄清;最小的獨立樣本仍然是一個非常好的主意。 – yzt

+0

調用諸如'printf'等可變參數函數絕不會導致調用用戶定義的轉換。如何定義「TRACE」? –

回答

0

通過將一個類實例傳遞給一個可變參數函數,您的程序展現出未定義的行爲。

認識到程序從未在添加之前或之後調用operator LPTSTR。編譯器不知道「%s」的含義(函數的實現)。它只是將實例轉儲到堆棧上,並且該函數看到%s,從堆棧中抓取四個字節,並相信它們是一個TCHAR*指針。

您的程序過去偶爾會偶然使用:CString類恰好包含TCHAR *指針作爲其唯一成員,因此它的內存表示與原始指針無法區分。實際上,這不是偶然的:這個類被精心設計成這樣,正是因爲MSVC程序員習慣於能夠將CString實例傳遞給printf等;有很多代碼都是圍繞着(非法)做你正在做的同樣的事情。

無論如何,我的猜測是,你的問題開始而不是當你添加更多的方法,你CString(無論是運算符重載或其他方式)的版本,但是當你添加更多非靜態數據成員,從而打破了仔細構建煙霧和鏡像系統。

+0

公平地說,MSVC可以自由定義它的喜好,這包括神奇的工作,這是未定義的行爲。 – Yakk

+0

@Yakk:是否有一個文檔頁面使其明確定義(顯然是以非便攜方式)? –

+0

@Igor:非常感謝,這是正確的。我認爲有一個選項可以爲這個指針定義一個默認的運算符:somesthing like「operator this(){return m_byMyData;}」 – user2294113