DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> JavaScript入門知識 >> AJAX入門 >> AJAX詳解 >> C++字符串完全指南(2)
C++字符串完全指南(2)
編輯:AJAX詳解     

MFC類
 
 
CString

MFC的CString含有TCHAR,它的實際字符類型取決於預處理標記的設置。通常,CString象STL字符串一樣是不透明對象,只能用CString的方法來修改。CString比STL字符串更優越的是它的構造函數接受MBCS和Unicode字符串。並且可以轉換為LPCTSTR,因此可以向接受LPCTSTR的函數直接傳遞CString對象,不必調用c_str()方法。

// 構造
CString s1 = "char string"; // 從LPCSTR構造
CString s2 = L"wide char string"; // 從LPCWSTR構造
CString s3 ( ' ', 100 ); // 預分配100字節,填充空格
CString s4 = "New window text";
// 可以在LPCTSTR處使用CString:
SetWindowText ( hwndSomeWindow, s4 );
// 或者,顯式地做強制類型轉換:
SetWindowText ( hwndSomeWindow, (LPCTSTR) s4 );


也可以從字符串表加載字符串。CString通過LoadString()來構造對象。用Format()方法可有選擇地從字符串表讀取一定格式的字符串。

// 從字符串表構造/加載
CString s5 ( (LPCTSTR) IDS_SOME_STR );  // 從字符串表加載
CString s6, s7;
// 從字符串表加載
  s6.LoadString ( IDS_SOME_STR );
// 從字符串表加載打印格式的字符串
  s7.Format ( IDS_SOME_FORMAT, "bob", nSomeStuff, ... );

第一個構造函數看上去有點怪,但它的確是文檔標定的字符串加載方式。

注意,CString只允許一種強制類型轉換,即強制轉換為LPCTSTR。強制轉換為LPTSTR (非常量指針)是錯誤的。按照老習慣,將CString強制轉換為LPTSTR只能傷害自己。有時在程序中沒有發現出錯,那只是碰巧。轉換到非常量指針的正確方法是調用GetBuffer()方法。

下面以往隊列加入元素為例說明如何正確地使用CString:

CString str = _T("new text");
LVITEM item = {0};
item.mask = LVIF_TEXT;
  item.iItem = 1;
  item.pszText = (LPTSTR)(LPCTSTR) str; // 錯!
  item.pszText = str.GetBuffer(0);      // 正確
ListVIEw_SetItem ( &item );
  str.ReleaseBuffer();  // 將隊列返回給str

pszText成員是LPTSTR,一個非常量指針,因此要用str的GetBuffer()。GetBuffer()的參數是CString分配的最小緩沖區。如果要分配一個1K的TCHAR,調用GetBuffer(1024)。參數為0,只返回指向字符串的指針。

上面示例的出錯語句可以通過編譯,甚至可以正常工作,如果恰好就是這個類型。但這不證明語法正確。進行非常量的強制類型轉換,打破了面向對象的封裝原則,並逾越了CString的內部操作。如果你習慣進行這樣的強制類型轉換,終會遇到出錯,可你未必知道錯在何處,因為你到處都在做這樣的轉換,而代碼也都能運行。
   
知道為什麼人們總在抱怨有缺陷的軟件嗎?不正確的代碼就臭蟲的滋生地。然道你願意編寫明知有錯的代碼讓臭蟲有機可乘?還是花些時間學習CString的正確用法讓你的代碼能夠100%的正確吧。

CString還有二個函數能夠從CString中得到BSTR,並在必要時轉換成Unicode。那就是AllocSysString()和SetSysString()。除了SetSysString()使用BSTR*參數外,二者一樣。

// 轉換成BSTR
CString s5 = "Bob!";
BSTR bs1 = NULL, bs2 = NULL;
bs1 = s5.AllocSysString();
  s5.SetSysString ( &bs2 );
// ...
  SysFreeString ( bs1 );
  SysFreeString ( bs2 );

COleVariant 與CComVariant 非常相似。COleVariant 繼承於VARIANT,可以傳遞給需要VARIANT的函數。但又與CComVariant 不同,COleVariant 只有一個LPCTSTR的構造函數,不提供單獨的LPCSTR和LPCWSTR的構造函數。在大多情況下,沒有問題,因為總是願意把字符串處理為LPCTSTR。但你必須知道這點。COleVariant 也有接受CString的構造函數。

// 構造
CString s1 = _T("tchar string");
COleVariant v1 = _T("Bob"); // 從LPCTSTR構造
COleVariant v2 = s1; // 從CString拷貝

對於CComVariant,必須直接處理VARIANT成員,用ChangeType()方法在必要時將其轉換為字符串。但是,COleVariant::ChangeType() 在轉換失敗時會拋出異常,而不是返回HRESULT的出錯碼。

// 數據萃取
COleVariant v3 = ...; // 從某種類型構造v3
BSTR bs = NULL;
try
    {
    v3.ChangeType ( VT_BSTR );
    bs = v3.bstrVal;
    }
  catch ( COleException* e )
    {
    // 出錯,無法轉換
    }
SysFreeString ( bs );

WTL類

CString

WTL的CString與MFC的CString的行為完全相同,參閱上面關於MFC CString的說明即可。

CLR 及 VC 7 類
System::String 是.Net的字符串類。在其內部,String對象是一個不變的字符序列。任何操作String對象的String方法都返回一個新的String對象,因為原有的String對象要保持不變。String類有一個特性,當多個String都指向同一組字符集時,它們其實是指向同一個對象。Managed Extensions C++ 的字符串有一個新的前綴S,用來表明是一個managed string字符串。

// 構造
String* ms = S"This is a nice managed string";

可以用unmanaged string字符串來構造String對象,但不如用managed string構造String對象有效。原因是所有相同的具有S前綴的字符串都指向同一個對象,而unmanaged string沒有這個特點。下面的例子可以說明得更清楚些:

String* ms1 = S"this is nice";
String* ms2 = S"this is nice";
String* ms3 = L"this is nice";
Console::WriteLine ( ms1 == ms2 ); // 輸出true
Console::WriteLine ( ms1 == ms3);  // 輸出false

要與沒有S前綴的字符串做比較,用String::CompareTo()方法來實現,如:

  Console::WriteLine ( ms1->CompareTo(ms2) );
  Console::WriteLine ( ms1->CompareTo(ms3) );

二者都輸出0,說明字符串相等。

在String和MFC 7的CString之間轉換很容易。CString可以轉換為LPCTSTR,String有接受char* 和 wchar_t* 的二種構造函數。因此可以直接把CString傳遞給String的構造函數:

  CString s1 ( "hello world" );
  String* s2 ( s1 );  // 從CString拷貝

反向轉換的方法也類似:

  String* s1 = S"Three cats";
  CString s2 ( s1 );

可能有點迷惑。從VS.Net開始,CString有一個接受String對象的構造函數,所以是正確的。

  CStringT ( System::String* pString );
為了加速操作,有時可以用基礎字符串(underlying string):

String* s1 = S"Three cats";
Console::WriteLine ( s1 );
const __wchar_t __pin* pstr = PtrToStringChars(s1);
for ( int i = 0; i < wcslen(pstr); i++ )
    (*const_cast<__wchar_t*>(pstr+i))++;
Console::WriteLine ( s1 );

PtrToStringChars() 返回指向基礎字符串的 const __wchar_t* 指針,可以防止在操作字符串時,垃圾收集器去除該字符串

XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved