C++字符串完全指南(2) - STL和ATL类
来源:互联网 发布:淘宝粘贴复制怎么弄 编辑:程序博客网 时间:2024/05/16 19:38
STL类STL只有一个字符串类,即basic_string。basic_string管理一个零结尾的字符数组。字符类型由模板参数决定。通常,basic_string被处理为不透明对象。可以获得一个只读指针来访问缓冲区,但写操作都是由basic_string的成员函数进行的。
basic_string预定义了二个特例:string,含有char类型字符;which,含有wchar_t类型字符。没有内建的TCHAR特例,可用下面的代码实现:
// 特例化typedef basic_string tstring; // TCHAR字符串// 构造string str = "char string"; // 从LPCSTR构造wstring wstr = L"wide char string"; // 从LPCWSTR构造tstring tstr = _T("TCHAR string"); // 从LPCTSTR构造// 数据萃取LPCSTR psz = str.c_str(); // 指向str缓冲区的只读指针LPCWSTR pwsz = wstr.c_str(); // 指向wstr缓冲区的只读指针LPCTSTR ptsz = tstr.c_str(); // 指向tstr缓冲区的只读指针
与_bstr_t 不同,basic_string不能在字符集之间进行转换。但是如果一个构造函数接受相应的字符类型,可以将由c_str()返回的指针传递给这个构造函数。例如:
// 从basic_string构造_bstr_t _bstr_t bs1 = str.c_str(); // 从LPCSTR构造 _bstr_t_bstr_t bs2 = wstr.c_str(); // 从LPCWSTR构造 _bstr_t
ATL类
CComBSTR
CComBSTR 是ATL的BSTR包装类。某些情况下比_bstr_t 更有用。最主要的是,CComBSTR允许操作隐含BSTR。就是说,传递一个CComBSTR对象给COM方法时,CComBSTR对象会自动管理BSTR内存。例如,要调用下面的接口函数:
// 简单接口struct IStuff : public IUnknown{ // 略去COM程序... STDMETHOD(SetText)(BSTR bsText); STDMETHOD(GetText)(BSTR* pbsText);};
CComBSTR 有一个BSTR操作方法,能将BSTR直接传递给SetText()。还有一个引用操作(operator &)方法,返回BSTR*,将BSTR*传递给需要它的有关函数。
CComBSTR bs1;CComBSTR bs2 = "new text";pStuff->GetText ( &bs1 ); // ok, 取得内部BSTR地址 pStuff->SetText ( bs2 ); // ok, 调用BSTR转换 pStuff->SetText ( (BSTR) bs2 ); // cast ok, 同上
CComVariant
CComBSTR有类似于 _bstr_t 的构造函数。但没有内建MBCS字符串的转换函数。可以调用ATL宏进行转换。
// 构造CComBSTR bs1 = "char string"; // 从LPCSTR构造CComBSTR bs2 = L"wide char string"; // 从LPCWSTR构造CComBSTR bs3 = bs1; // 拷贝CComBSTRCComBSTR bs4;bs4.LoadString ( IDS_SOME_STR ); // 从字符串表加载// 数据萃取BSTR bstr1 = bs1; // 返回内部BSTR,但不可修改!BSTR bstr2 = (BSTR) bs1; // cast ok, 同上BSTR bstr3 = bs1.Copy(); // 拷贝bs1, 返回BSTRBSTR bstr4;bstr4 = bs1.Detach(); // bs1不再管理它的BSTR// ...SysFreeString ( bstr3 );SysFreeString ( bstr4 );
上面的最后一个示例用到了Detach()方法。该方法调用后,CComBSTR对象就不再管理它的BSTR或其相应内存。所以bstr4就必须调用SysFreeString()。
最后讨论一下引用操作符(operator &)。它的超越使得有些STL集合(如list)不能直接使用CComBSTR。在集合上使用引用操作返回指向包容类的指针。但是在CComBSTR上使用引用操作,返回的是BSTR*,不是CComBSTR*。不过可以用ATL的CAdapt类来解决这个问题。例如,要建立一个CComBSTR的队列,可以声明为:
std::list< CAdapt> bstr_list;
CAdapt 提供集合所需的操作,是隐含于代码的。这时使用bstr_list 就象在操作一个CComBSTR队列。
CComVariant
CComVariant 是VARIANT的包装类。但与 _variant_t 不同,它的VARIANT不是隐含的,可以直接操作类里的VARIANT成员。CComVariant 提供多种构造函数和多类型操作。这里只介绍与字符串有关的操作。
// 构造CComVariant v1 = "char string"; // 从LPCSTR构造CComVariant v2 = L"wide char string"; // 从LPCWSTR构造CComBSTR bs1 = "BSTR bob";CComVariant v3 = (BSTR) bs1; // 从BSTR拷贝// 数据萃取CComBSTR bs2 = v1.bstrVal; // 从VARIANT提取BSTR
跟_variant_t 不同,CComVariant没有不同VARIANT类型之间的转换操作。必须直接操作VARIANT成员,并确定该VARIANT的类型无误。调用ChangeType()方法可将CComVariant数据转换为BSTR。
CComVariant v4 = ... // 从某种类型初始化 v4CComBSTR bs3;if ( SUCCEEDED( v4.ChangeType ( VT_BSTR ) )) bs3 = v4.bstrVal;
跟 _variant_t 一样,CComVariant不能直接转换为MBCS字符串。要建立一个过渡的_bstr_t 变量,用其它提供转换Unicode到MBCS的类函数,或ATL转换宏来转换。
ATL转换宏
ATL转换宏
ATL的字符串转换宏可以方便地转换不同编码的字符,用在函数中很有效。宏按照[source type]2[new type] 或 [source type]2C[new type]格式命名。后者转换为一个常量指针 (名字内含"C")。类型缩写如下:
A:MBCS字符串,char* (A for ANSI)
W:Unicode字符串,wchar_t* (W for wide)
T:TCHAR字符串,TCHAR*
OLE:OLECHAR字符串,OLECHAR* (实际等于W)
BSTR:BSTR (只用于目的类型)
例如,W2A() 将Unicode字符串转换为MBCS字符串,T2CW()将TCHAR字符串转换为Unicode字符串常量。
要使用宏转换,程序中要包含atlconv.h头文件。可以在非ATL程序中使用宏转换,因为头文件不依赖其它的ATL,也不需要 _Module全局变量。如在函数中使用转换宏,在函数起始处先写上USES_CONVERSION宏。它表明某些局部变量由宏控制使用。
转换得到的结果字符串,只要不是BSTR,都存储在堆栈中。如果要在函数外使用这些字符串,就要将这些字符串拷贝到其它的字符串类。如果结果是BSTR,内存不会自动释放,因此必须将返回值分配给一个BSTR变量或BSTR的包装类,以避免内存泄露。
下面是若干宏转换示例:
// 带有字符串的函数:void Foo ( LPCWSTR wstr );void Bar ( BSTR bstr );// 返回字符串的函数:void Baz ( BSTR* pbstr );#include main(){using std::string;USES_CONVERSION; // 声明局部变量由宏控制使用// 示例1:送一个MBCS字符串到Foo()LPCSTR psz1 = "Bob";string str1 = "Bob";Foo ( A2CW(psz1) ); Foo ( A2CW(str1.c_str()) );// 示例2:将MBCS字符串和Unicode字符串送到Bar()LPCSTR psz2 = "Bob";LPCWSTR wsz = L"Bob";BSTR bs1;CComBSTR bs2;bs1 = A2BSTR(psz2); // 创建 BSTR bs2.Attach ( W2BSTR(wsz) ); // 同上,分配到CComBSTRBar ( bs1 ); Bar ( bs2 );SysFreeString ( bs1 ); // 释放bs1 // 不必释放bs2,由CComBSTR释放。// 示例3:转换由Baz()返回的BSTRBSTR bs3 = NULL;string str2;Baz ( &bs3 ); // Baz() 填充bs3内容str2 = W2CA(bs3); // 转换为MBCS字符串 SysFreeString ( bs3 ); // 释放bs3}可以看到,向一个需要某种类型参数的函数传递另一种类型的参数,用宏转换是非常方便的。
- C++字符串完全指南(2) - STL和ATL类
- C++字符串完全指南(2) - STL和ATL类
- C++字符串完全指南(2) - STL和ATL类
- C++字符串完全指南(2) - STL和ATL类
- C++字符串完全指南 - STL和ATL类
- C++字符串完全指南 - 各种字符串类
- C++字符串完全指南 - 各种字符串类
- C++字符串完全指南
- C++字符串完全指南(2) - MFC类
- C++字符串完全指南(2) - MFC类
- C++字符串完全指南(2) - MFC类
- C++字符串完全指南(2) - MFC类
- 【C/C++】STL,ATL,WTL之间的联系和区别
- C++字符串完全指南(2)
- C++字符串完全指南(2) - 各种字符串类- CRT类
- C++字符串完全指南(2) - 各种字符串类- CRT类
- C++字符串完全指南(2) - 各种字符串类- CRT类
- C++字符串完全指南(2) - 各种字符串类- CRT类
- C++字符串完全指南(2) - 各种字符串类(一)
- PowerDesigner12.5 破解方法
- 2011总结
- C++字符串完全指南(2) - 各种字符串类- CRT类
- linux和windows远程连接
- C++字符串完全指南(2) - STL和ATL类
- VirtualBox 网络设置
- Java反射机制的原理及在Android下的简单应用
- Linux的shell编程——判断语句
- getopt 使用
- js javascript:void(0) 真正含义
- Linux的shell编程——数学运算
- HttpClient 的 abort(终止)程序示例
- Linux的shell编程——while的使用