LPCWSTR
LPCWSTR 是Unicode字元串指針,typedef __nullterminated CONST WCHAR *LPCWSTR, *PCWSTR; in WinNT.h
Convert example:
LPCWSTR text;
LPWSTR l=const_cast<LPWSTR>(text);
unsigned int maxResultSize=100;
const std::wstring ws=something;
LPWSTR lp;
wcsncpy_s(lp, maxResultSize, ws.c_str(), ws.size();
在頭檔案<atlconv.h>中定義了ATL提供的所有轉換宏,如:
A2CW (LPCSTR) -> (LPCWSTR)
A2W (LPCSTR) -> (LPWSTR)
W2CA (LPCWSTR) -> (LPCSTR)
W2A (LPCWSTR) -> (LPSTR)
所有的宏如下表所示:
A2BSTR
OLE2A
T2A
W2A
A2COLE
OLE2BSTR
T2BSTR
W2BSTR
A2CT
OLE2CA
T2CA
W2CA
A2CW
OLE2CT
T2COLE
W2COLE
A2OLE
OLE2CW
T2CW
W2CT
A2T
OLE2T
T2OLE
W2OLE
A2W
OLE2W
T2W
W2T
上表中的宏函數,非常的有規律,每個字母都有确切的含義如下:
2
to 的發音和 2 一樣,是以借用來表示“轉換為、轉換到”的含義。
A
ANSI 字元串,也就是 MBCS。
W、OLE
寬字元串,也就是 UNICODE。
T
中間類型T。如果定義了 _UNICODE,則T表示W;如果定義了 _MBCS,則T表示A
C
const 的縮寫
利用這些宏,可以快速的進行各種字元間的轉換。使用前必須包含頭檔案,并且申明USER_CONVERSION;使用 ATL 轉換宏,由于不用釋放臨時空間,是以使用起來非常友善。但是考慮到棧空間的尺寸(VC 預設2M),使用時要注意幾點:
1、隻适合于進行短字元串的轉換;
2、不要試圖在一個次數比較多的循環體内進行轉換;
3、不要試圖對字元型檔案内容進行轉換,因為檔案尺寸一般情況下是比較大的;
4、對情況 2 和 3,要使用 MultiByteToWideChar() 和 WideCharToMultiByte();
2.HRESULT
HRESULT 是一種簡單的資料類型,通常被屬性和 ATL 用作傳回值。下表說明各種不同的值。頭檔案 winerror.h 中包含更多的值。
HRESULT 其實是一個雙位元組的值,其最高位(bit)如果是0表示成功,1表示錯誤。
HRESULT hr = 調用元件函數;
if( SUCCEEDED( hr ) ){...} // 如果成功
......
if( FAILED( hr ) ){...} // 如果失敗
3.什麼是BSTR
BSTR是“Basic STRing”的簡稱,微軟在COM/OLE中定義的标準字元串資料類型。
對于C++,Windows頭檔案wtypes.h中定義如下:
typedef wchar_t WCHAR;
typedef WCHAR OLECHAR;
typedef OLECHAR __RPC_FAR *BSTR;;
字元串相關類型的推薦選擇順序
優先級
類型
說明
最高
stl::string/wstring
●功能最完善,可移植性最好。
CString
●如果編碼規範限制使用STL的時候,推薦CString。 ●VC 6的版本很不完善。.Net有明顯改進,需要進一步研究
C/C++ basic type
(TCHAR* / char* /
LPTSTR / LPCTSTR / TCHAR[])
●在結構體中,優先使用指定最大長度的字元數組。 ●效率最好
CComBSTR/ _bstr_t
●在必須使用BSTR時的優先選擇。
●在ATL(COM component)工程或者工程中必須使用ATL中,優先選擇CComBSTR。一般Exe/dll如果_bstr_t能滿足要求,優先使用_bstr_t。
●對于VC6,使用_bstr_t一定要慎重,最好隻用作簡單臨時變量儲存調被調用函數的傳入參數。因為_bstrt_t不能支援一些關鍵性操作,比如Detach。
● 對于VC++ .Net推薦使用_bstr_t,它是C++擴充,不需要額外包含ATL的檔案。
最低
BSTR
● COM接口
4.CComBSTR
1. char
基本類型,1 byte 的串
2. wchar_t
unicode 串 2 byte
3. TCHAR
在16位程式下,表示為char,單位元組
在32位程式下,表示為unicode,兩位元組
4. 根據上面産生許多變種,一般都有相應的大定形式; 當在其中有P時,表示指針; 當在其中有C時,表示是常量
5. BSTR
定義的資料類型,一般COM調用的參數串
當define _UNICODE 它表示unicode串
否則 它表示ansi串
對了, 它前面有一個長度
6. CString _bstr_t CComBSTR 這三個是最好的東東
CString 封裝了char 與 w_char_t
_bstr_t 封裝了BSTR
CComBSTR 封裝了BSTR
CComBSTR、_bstr_t、BSTR、LPCTSTR、LPSTR、char *、CString
CComBSTR 是專門為COM的通用性而定制的一種格式
BSTR : unsigned short* 32位字元指針
LPCTSTR const char* 指向字元串常量的32位指針
char *; 字元串指針。
CString 字元串類。
LPTSTR const char* 指向可移植到Unicode和DBCS字元串常量的32位指針
LPSTR char * 可移植為的Unicode和DBCS字元串的32位指針。
4.std::wstring
const std::wstring obj;
const wchar_t *wt= obj.c_str();
Code : std::wstring ws;
ws=ws + L"" + BSTR
第0種方法:
std::wstring s2ws(const std::string& s)
{
std::wstring temp(s.length(),L‘ ‘);
std::copy(s.begin(), s.end(), temp.begin());
return temp;
}
std::string ws2s(const std::wstring& s)
std::string temp(s.length(), ‘ ‘);
第一種方法:調用WideCharToMultiByte()和MultiByteToWideChar(),
#include <string>
#include <windows.h>
using namespace std;
//Converting a WChar string to a Ansi string
std::string WChar2Ansi(LPCWSTR pwszSrc)
int nLen = WideCharToMultiByte(CP_ACP, 0, pwszSrc, -1, NULL, 0, NULL, NULL);
if (nLen<= 0) return std::string("");
char* pszDst = new char[nLen];
if (NULL == pszDst) return std::string("");
WideCharToMultiByte(CP_ACP, 0, pwszSrc, -1, pszDst, nLen, NULL, NULL);
pszDst[nLen -1] = 0;
std::string strTemp(pszDst);
delete [] pszDst;
return strTemp;
string ws2s(wstring& inputws){ return WChar2Ansi(inputws.c_str()); }
//Converting a Ansi string to WChar string
std::wstring Ansi2WChar(LPCSTR pszSrc, int nLen)
int nSize = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pszSrc, nLen, 0, 0);
if(nSize <= 0) return NULL;
WCHAR *pwszDst = new WCHAR[nSize+1];
if( NULL == pwszDst) return NULL;
MultiByteToWideChar(CP_ACP, 0,(LPCSTR)pszSrc, nLen, pwszDst, nSize);
pwszDst[nSize] = 0;
if( pwszDst[0] == 0xFEFF) // skip Oxfeff
for(int i = 0; i < nSize; i ++)
pwszDst[i] = pwszDst[i+1];
wstring wcharString(pwszDst);
delete pwszDst;
return wcharString;
std::wstring s2ws(const string& s){ return Ansi2WChar(s.c_str(),s.size());}
第二種方法:采用ATL封裝_bstr_t的過渡:(注,_bstr_是Microsoft Specific的,是以下面代碼可以在VS2005通過,無移植性);
#include <comutil.h>
#pragma comment(lib, "comsuppw.lib")
string ws2s(const wstring& ws);
wstring s2ws(const string& s);
string ws2s(const wstring& ws)
_bstr_t t = ws.c_str();
char* pchar = (char*)t;
string result = pchar;
return result;
wstring s2ws(const string& s)
_bstr_t t = s.c_str();
wchar_t* pwchar = (wchar_t*)t;
wstring result = pwchar;
5.std::pair
#include <iostream>
#include <utility>
03
04
05
06
int main () {
07
pair <string,double> product1 ("tomatoes",3.25);
08
pair <string,double> product2;
09
pair <string,double> product3;
10
11
product2.first = "lightbulbs"; // type of first is string
12
product2.second = 0.99; // type of second is double
13
14
product3 = make_pair ("shoes",20.0);
15
16
cout << "The price of " << product1.first << " is $" << product1.second << "/n";
17
cout << "The price of " << product2.first << " is $" << product2.second << "/n";
18
cout << "The price of " << product3.first << " is $" << product3.second << "/n";
19
return 0;
20
6.std::vector
簡單來講,std::vector 是一個動态數組,管理的是一塊線性的、可動态增長的記憶體。
如何加速 std::vector?
使用 vector::reserve
在大緻可預估 vector 大小時,在插入資料前,應該先調用 reserve(size) 進行記憶體的預配置設定(這裡 size是預估的vector元素個數)。
避免在vector開始(begin)插入/删除資料
也就是說,應該盡量用 vector::insert(end(), …) 或者 vector::push_back/pop_back添加/删除資料。而不要用 vector::insert(begin(), …)操作。vector 沒有提供 push_front操作,原因隻有一個:從 vector 開始處插入/删除資料是低效的做法。
如果你需要大量的在容器開始(begin)處 insert 資料,那麼可以選擇 std::deque(有 vector随機通路的優點,也有 list 高效插入的優點)或者 std::list.
std::vector 的缺陷
什麼時候不能用 std::vector ?
在容器需要容納海量資料,并且元素個數不可預知時,堅決不能用 std::vector.所有基于線性記憶體的資料結構(如std::vector,std::string)在海量資料時,遭遇性能瓶頸。
記憶體碎片
基于線性記憶體的資料結構(如 std::vector,std::string),還有一個典型的問題,就是容易産生記憶體碎片。在大量操作std::vector 或 std::string 後,記憶體碎片就會比較嚴重。
std::vector 與 allocator
我們知道,std::vector 的原型是:
template >
class vector;
那麼是否需要像我們針對Map/MultiMap、Set/MultiSet、List/Slist、HashMap/HashMultiMap、HashSet/HashMultiSet、Deque 做的那樣,将 AllocT 改用 GC Allocator呢?
答案是:不需要。GC Allocator 對于改善小記憶體配置設定是有益的。但是在動态的線性記憶體的資料結構無效。這樣的資料結構除了std::vector 外,典型的還有 std::string(std::basic_string)。
7._bstr_t
bstr_t類封裝BSTR有趣的地方就是它的封裝方式有點類似于智能指針,又有點像COM管理生存期的方式。_bstr_t将兩者結合起來并具體展現在構造函數、指派函數和析構函數中。
_variant_t和_bstr_t這兩個類分别封裝并管理VARIANT和BSTR這兩種資料類型,
VARIANT和BSTR這兩種類型是COM中使用的資料類型。
為了C++中的變量應用到ADO程式設計中,隻能進行資料類型的轉換。
通過_variant_t和_bstr_t這兩個類,就可以友善的把C++類型變量轉換成COM中的變量了
ADO是基于COM接口x實作的是以ta它的使用對于正在進行的 COMCOM程式設計的程式員而言更簡單
COMshi使用其特定的資料類型,_bstr_t是其中一種源類型
其他類型轉換成_bstr_t可以直接指派。
例子:
_bstr_t bstr("程式員");
const char *buf=bstrVar;
_bstr_t t("123");
t.GetBSTR();
_variant_t((LONG)value);
_variant_t v(something);
v.vt==VT_EMPTY || v.vt==VT_BSTR || v.vt==VT_NULL
8.boost::function
1. 介紹
Boost.Function 庫包含了一個類族的函數對象的包裝。它的概念很像廣義上的回調函數。其有着和函數指針相同的特性但是又包含了一個調用的接口。一個函數指針能夠在能以地方被調用或者作為一個回調函數。boost.function能夠代替函數指針并提供更大的靈活性。
2. 使用
Boost.Function 有兩種形式:首選形式和便攜式形式, 其文法如下:
首選形式
便攜式形式
boost::function<float(int x, int y)>f
boost::function2<float, int, int>f
但是便攜式形式不是所有的編譯器都支援的, 是以這裡我隻介紹首選形式。
2.1 普通函數
我們可以看下如下的例子:
1 void do_sum(int *values, int n)
2 {
3 int sum(0);
4 for (int i = 0; i < n; ++i)
5 {
6 sum += values[i];
7 }
8 cout << sum << endl;
9 };
10 int _tmain(int argc, _TCHAR* argv[])
11 {
12 boost::function<void(int *values, int n)> sum;
13 sum = &do_sum;
14 int a[] = {1,2,3,4,5};
15 sum(a, 5);
16 return 0;
17 }
sum 可以了解為一個廣義的函數對象了,其隻用就是儲存函數do_sum, 然後再調用之。
2.2 成員函數
在很多系統中, 對于類的成員函數的回調需要做特殊處理的。這個特殊的處理就是“參數綁定”。當然這個超出了我們讨論的範圍了。 boost::function對于成員函數的使用可以看下如下代碼:
1 class X{
2 public:
3 int foo(int a)
4 {
5 cout << a <<endl;
6 return a;
8 };
9 int _tmain(int argc, _TCHAR* argv[])
10 {
11 boost::function<int(X*, int)>f;
12 f = &X::foo;
13 X x;
14 f(&x, 5);
15 return 0;
16 }
我們發現, 對類的成員函數的對象化從文法是沒有多大的差別。
3. 一個典型的例子
上面的幾個例子沒有展現出boost::function的作用來, 這裡在寫一個例子。比如當程式執行到某一處的時候想綁定某一個函數, 但是不想立即執行, 我們就可以聲明一個函數對象,給此對象綁定相應的函數, 做一些其他事情,然後再來執行綁定的函數, 代碼如下:
1 void print(int a)
3 cout << a << endl;
4 }
5 typedef boost::function<void (int)> SuccessPrint;
6 int _tmain(int argc, _TCHAR* argv[])
7 {
8 vector<SuccessPrint> printList;
9 SuccessPrint printOne = boost::bind(print, _1);
10 printList.push_back(printOne);
11 SuccessPrint printTwo = boost::bind(print, _1);
12 printList.push_back(printTwo);
13 SuccessPrint printThree = boost::bind(print, _1);
14 printList.push_back(printTwo);
15 // do something else
16 for (int i = 0; i < printList.size(); ++i)
17 printList.at(i)(i);
18 return 0;
19 }
上述代碼中首先把聲明一個函數對象 typedef boost::function<void (int)> SuccessPrint, 然後把print綁定到斥對象中, 放入vector中, 到最後才來執行這print()函數。
Others:
boost::lexical_cast
boost::lexical_cast<std::wstring>(
boost::posix_time
boost::shared_ptr<DatabaseUtils>
boost::shared_ptr<PolicyPath::PoliciesVector>
boost::wformat
boost::bind(
boost::mem_fn(
boost::optional<>
boost::function<delegate * ...>