WEB开发网
开发学院软件开发C++ C++字符串完全指引之二:字符串封装类 阅读

C++字符串完全指引之二:字符串封装类

 2010-10-15 09:08:04 来源:Web开发网   
核心提示:STL 类STL只有一个字符串类,basic_string,C++字符串完全指引之二:字符串封装类(4),一个basic_string管理一个以0做结束符的字符串数组,字符的类型是basic_string模般的参数,你可以这样声明一个CComBSTR的list:std::list< CAdapt<CComB

STL 类

STL只有一个字符串类,basic_string。一个basic_string管理一个以0做结束符的字符串数组。字符的类型是basic_string模般的参数。总的来说,一个basic_string类型的变量应该被当作不透明的对象。你可以得到一个指向内部缓冲区的只读指针,但是任何写操作必须使用basic_string的操作符和方法。

basic_string有两个预定义的类型:包含char的string类型和包含wchar_t的wstring类型。这里没有内置的包含TCHAR的类型,但是你可以使用下面列出的代码来实现。

// Specializations
typedef basic_string tstring; // string of TCHARs
// Constructing
string str = "char string";     // construct from a LPCSTR
wstring wstr = L"wide char string"; // construct from a LPCWSTR
tstring tstr = _T("TCHAR string"); // construct from a LPCTSTR
// Extracting data
LPCSTR psz = str.c_str();  // read-only pointer to str''s buffer
LPCWSTR pwsz = wstr.c_str(); // read-only pointer to wstr''s buffer
LPCTSTR ptsz = tstr.c_str(); // read-only pointer to tstr''s buffer

不像_bstr_t,一个basic_string变量不能在字符集之间直接转换。然而,你可以传递由c_str()返回的指针给另外一个类的构造函数(如果这个类的构造函数接受这种字符类型)。例如:

// Example, construct _bstr_t from basic_string
_bstr_t bs1 = str.c_str(); // construct a _bstr_t from a LPCSTR
_bstr_t bs2 = wstr.c_str(); // construct a _bstr_t from a LPCWSTr

ATL 类

CComBSTR

CComBSTR 是 ATL 中的 BSTR 封装类,它在某些情况下比_bstr_t有用的多。最引人注意的是CComBSTR允许访问底层的BSTR,这意味着你可以传递一个CComBSTR对象给COM的方法。CComBSTR对象能够替你自动的管理BSTR的内存。例如,假设你想调用下面这个接口的方法:

// Sample interface:
struct IStuff : public IUnknown
{
 // Boilerplate COM stuff omitted...
 STDMETHOD(SetText)(BSTR bsText);
 STDMETHOD(GetText)(BSTR* pbsText);
};

CComBSTR有一个操作符--BSTR方法,所以它能直接被传给SetText()函数。还有另外一个操作--&,这个操作符返回一个BSTR*。所以,你可以对一个CComBSTR对象使用&操作符,然后把它传给需要BSTR*参数的函数。

CComBSTR bs1;
CComBSTR bs2 = "new text";
 pStuff->GetText ( &bs1 );    // ok, takes address of internal BSTR
 pStuff->SetText ( bs2 );    // ok, calls BSTR converter
 pStuff->SetText ( (BSTR) bs2 ); // cast ok, same as previous line

CComBSTR有和_bstr_t相似的构造函数,然而却没有内置的向MBCS字符串转换的函数。因此,你需要使用一个ATL转换宏。

// Constructing
CComBSTR bs1 = "char string";    // construct from a LPCSTR
CComBSTR bs2 = L"wide char string"; // construct from a LPCWSTR
CComBSTR bs3 = bs1;         // copy from another CComBSTR
CComBSTR bs4;
 bs4.LoadString ( IDS_SOME_STR ); // load string from string table
// Extracting data
BSTR bstr1 = bs1;    // returns internal BSTR, but don''t modify it!
BSTR bstr2 = (BSTR) bs1; // cast ok, same as previous line
BSTR bstr3 = bs1.Copy(); // copies bs1, returns it as a BSTR
BSTR bstr4;
 bstr4 = bs1.Detach(); // bs1 no longer manages its BSTR
 // ...
 SysFreeString ( bstr3 );
 SysFreeString ( bstr4 );

注意在上个例子中使用了Detach()方法。调用这个方法后,CComBSTR对象不再管理它的BSTR字符串或者说它对应的内存。这就是bstr4需要调用SysFreeString()的原因。

做一个补充说明:重载的&操作符意味着在一些STL容器中你不能直接使用CComBSTR变量,比如list。容器要求&操作符返回一个指向容器包含的类的指针,但是对CComBSTR变量使用&操作符返回的是BSTR*,而不是CComBSTR*。然而,有一个ATL类可以解决这个问题,这个类是CAdapt。例如,你可以这样声明一个CComBSTR的list:

std::list< CAdapt<CComBSTR> > bstr_list;

CAdapt提供容器所需要的操作符,但这些操作符对你的代码是透明的。你可以把一个bstr_list当作一个CComBSTR的list来使用。

上一页  1 2 3 4 5 6 7 8 9  下一页

Tags:字符串 完全 指引

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接