它的工作原理是因爲CString類的第一個元素是指向char數組的指針。實際上CString中唯一的字段是指向字符串數組的指針。這個類使用一些技巧來隱藏內部數據(比如字符串長度,保留緩衝區大小等),然後分配一個大緩衝區,然後讓唯一的類指針指向char數組,以便到達那些內部數據字段,它將該指針移動到已知位置抵消。
你應該做的是調用s.GetBuffer(0);或(LPCTSTR);但使用它作爲
sprintf(z2, "%s", ss);
被allowd由MFC創作者的設計,當然它工作在Windows下它可能會崩潰其他平臺。
[評論後編輯]
你的代碼將是如果不是C風格的強制轉型樣(LPCTSTR)s
更安全,你會使用C++投:static_cast<LPCTSTR>(s);
。但很快你會發現你的代碼在所有這些static_cast-s中變得很難看,特別是如果你的sprintf有很多參數的話。據我所知(在我看來),就設計而言,C++風格的轉換旨在讓您重新思考您的設計,而不是根本不使用轉換。在你的情況,而不是使用sprintf的,你應該使用std :: wstringstream(假設你使用UNICODE編譯):
#include<sstream>
std::wostream & operator<< (std::wostream &out, CString const &s) {
out << s.GetString();
return out;
}
int main(){
CString s = _T("test");
std::wstringstream ss;
ss << s; // no cast required, no UB here
std::wcout << ss.str();
return 0;
}
調用的正確方法是**'CString :: GetString()'**,**不** **'GetBuffer()'。還要注意_C風格的轉換是壞的:請使用** C++風格的轉換**:'static_cast(ss)'。 –
更確切地說,在你的情況下,因爲你正在使用'sprintf()'(而不是像'_stprintf_s()')這樣的基於TCHAR的函數,所以應該使用'static_cast(ss)'。這樣,在Unicode構建(自VS2005以來一直是默認構造),其中'CString'實際上是'CStringW',轉換失敗並且代碼不能編譯,您可以修復它(而不是傳遞錯誤的參數到'sprintf()',並在運行時靜靜地引入一個bug)。 –
'ss'是示例中的'std :: string',ITYM's.GetBuffer(0)'等等。否則就是'ss.c_str()'。 – MSalters