青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

hdqqq

  C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
  35 隨筆 :: 0 文章 :: 104 評論 :: 0 Trackbacks

#

?????? 上一篇講到了根據一個typelist實現一個結構,這個結構帶有typelist中所有類型的成員,同時,可以通過Field0,Field1等接口訪問和賦值.在這個基礎上,我們可以構建對應一條記錄的結構data_row,

二.一條記錄

#define?ROW_NO_CHANGE?0
#define?ROW_ADD?
1
#define?ROW_UPDATE?
2
#define?ROW_DELETE?
3

template
<typename?_tlist>
class?data_op_record_row?:?
public?struct_mem<_tlist>
{
public:
????enum?_enum_RowState?{
????????_en_Row_NoChange?
=?ROW_NO_CHANGE,????//未修改
????????_en_Row_Add?
=?ROW_ADD,????????????//新增記錄
????????_en_Row_Update?
=?ROW_UPDATE,????????//更新
????????_en_Row_Del?
=?ROW_DELETE,????????//刪除
????}?m_en_State;
public:
????void?SetState(
int?newstate)?{
????????
if?(m_en_State?!=?newstate)?{
????????????
if?(newstate?==?_en_Row_NoChange?||?
????????????????newstate?
==?_en_Row_Add?||?
????????????????newstate?
==?_en_Row_Update?||?
????????????????newstate?
==?_en_Row_Del)?
????????????{
????????????????m_en_State?
=?(_enum_RowState)newstate;
????????????}
????????}
????}
public:
????data_op_record_row?()?:?m_en_State(_en_Row_NoChange)?{}
????~data_op_record_row?(){}
protected:
private:
};
上面的類增加了一個枚舉,標識這條記錄當前的狀態,在記錄集中,將根據記錄的狀態進行相關的操作.這個其實類似與.net中的DataRow,不過.net中的DataRow可以用wizzard生成需要的類,而這里是用模板生成的.

三.數據類型轉換
????? 數據庫中的表對應的字段有不同的數據類型,ADO操作接口中用不同的數據類型與之對應,其中Field接口的GetType就是返回字段類型的,但是ADO的GetValue返回的是_variant_t類型,為了實際業務的需要,還需要轉換成不同的類型,因此,需要對_variant_t類型進行轉換.為此需要提供模板轉換函數

template?<typename?_type>
void?DbData_Change(_type
&?ret,?_variant_t&?field)
{
???AfxMessageBox(
"未定義的數據轉換");
}


template?
<>
void?DbData_Change
<int>(int?&?ret,?_variant_t&?field)
{
????ret?
=?field.lVal;
}

template?
<>
void?DbData_Change
<std::string>(std::string&?ret,?_variant_t&?field)
{
????_bstr_t?temp;

????
if?(field.vt?!=?VT_NULL)?{
????????temp?
=?field.bstrVal;
????????ret?
=?temp.operator?const?char*();
????}
}

template?
<>
void?DbData_Change
<bool>(bool&?ret,?_variant_t&?field)
{
????ret?
=?(field.boolVal?==?(short)0xFFFF???TRUE?:?FALSE);
}

template?
<>
void?DbData_Change
<double>(double&?ret,?_variant_t&?field)
{
????
if?(field.vt?!=?VT_NULL)?{
????????
//ret?=?field.cyVal;
????????ret?
=?field.dblVal;
????}
else?{
????????ret?
=?0;
????}
}

上面的模板函數的功能是從_variant_t轉換到某中數據類型,對于其它類型還可以進行擴充,對于沒有進行特化的函數,編譯器會使用缺省模板,在運行時候就會出現提示.有了上面的函數,現在我們需要一個數據類型的封裝類,使得被封裝的類型可以自動進行從_variant_t類型的需要類型的轉換,所以有了下面的封裝類.
//數據庫數據類型封裝
template?
<typename?_type>
class?_db_data_wrapper
{
public:
????_type
&?Value()?{
????????return?m_Data;
????}

????
const?_type&?operator?=(const?_type&?value)?{
????????m_Data?
=?value;
????????return?value;
????}

????_db_data_wrapper
&?operator?=?(const?_db_data_wrapper&?other)?{
????????
if?(this?!=?&other)?{
????????????m_Data?
=?other.m_Data;
????????}
????????return?
*this;
????}

public:
????virtual?void?GetDbValue(_variant_t
&?field_value)?{
????????DbData_Change(m_Data,?field_value);
????}

public:
????_db_data_wrapper(){}
????_db_data_wrapper(
const?_type&?value)?:?m_Data(value)?{}
????~_db_data_wrapper(){}
private:
????_type?m_Data;
};

typedef?_db_data_wrapper
<?int?>?DB_INT;
typedef?_db_data_wrapper
<?std::string?>?DB_STRING;
typedef?_db_data_wrapper
<?bool?>?DB_BOOL;
typedef?_db_data_wrapper
<?double?>?DB_DOUBLE;



上面的代碼預定義了幾種常用的數據類型,這個數據的封裝類支持 = 操作符,因此可以直接用被封裝的數據對其賦值.象下面
int?i?=?4;
DB_INT?di;
di?
=?i;
i?
=?di.Value();


同時通過成員函數GetDbValue(_variant_t& field_value), 支持從_variant_t轉換為自身封裝的類型.

現在,可以用上面的數據類型構建記錄結構了

typedef data_op_record_row< TYPELIST_2(DB_INT,DB_STRING) > my_DataRow;

在上面的my_DataRow類型中,有兩個成員Field0, Field1,類型分別為 DB_INT,DB_STRING, 支持_variant_t類型轉換.

當然,用wrapper對數據進行封裝在實際的使用中畢竟有些麻煩, 如數據必須通過 Value() 函數來取得,如果直接使用象 int, std::string 等類型作為 記錄結構的成員,也可以實現_variant自動轉換,但是需要在上一層的記錄集類中加入相關的轉換操作,實現起來比較麻煩,所以我這里選擇了對數據進行封裝.


?

posted @ 2007-01-22 17:33 hdqqq 閱讀(1253) | 評論 (1)編輯 收藏

???? c++在數據庫開發這種需要進行快速開發的地方一直是以效率低下著稱,borland 的c++ build 依賴vcl提供的組件勉強可以實現,但是由于用的是pascal的東西,根基不行,一直叫不響.再看看現在流行的數據庫,sql server 和mysql 等雖然提供本地開發的頭文件和庫,但是對于一些可能使用不同數據庫的應用來說,選擇特定某種數據庫開發顯然是不妥,因此,象ado這種數據操作接口大行其道.這又給用c++開發帶來了麻煩,象vb等工具可以自動轉換variant類型,但是在vc使用的時候卻很麻煩.網上那些使用ado接口的c++的例子,大多數都從#import 那個dll開始, 然后就是繁瑣的創建instance,打開記錄集,最后還要進行一個variant到c++類型的轉換,確實是夠麻煩的,難怪效率低下.
?
??? 在很多情況下,一些數據查詢和數據操作往往是在開發的時候就確定下來了,比如說你有個用戶表要操作,你在開發的時候就知道這個表中的所有字段名稱和字段類型,但是你用ado,你卻還是要和繁瑣的variant打交道,把它轉換為你想要的數據類型. 如果能實現一個類,在知曉數據表字段類型的情況下,可以方便地使用c++數據類型,并且可以進行諸如插入,刪除,更新等操作,那就方便多了.? 這就是本文想實現的目標.? 但是對于那些在運行時候才確定的數據操作,如用戶輸入一個 sql 查詢,然后再來進行操作,對于象c++ 這種強類型的語言來說,可能除了使用 variant別無他法, 對于這方面,本文沒有給出解決辦法.

本文中的代碼在vc6下編譯通過
需要的庫 loki for vc6, boost

一. 構造記錄結構

?? 通常來說,數據集由一條條的記錄組成,記錄下有字段,記錄是數據操作的基本單元.照c++的習慣,最好是一條記錄一個結構,字段就是這個結構的成員,然后用列表或者vector組合一下就是記錄集了.但是一條記錄的字段是有可能變動的,還好,有loki 的 typelist.

?

?1?#if?!defined(INCLUDE_40697E96_B6DE_449D_A516_B0376650A488)
?2?#define?INCLUDE_40697E96_B6DE_449D_A516_B0376650A488
?3?
?4?#if?_MSC_VER?>?1000
?5?#pragma?once
?6?#endif
?7?
?8?#include?<typelist.h>
?9?#include?<functor.h>
10?#include?<boost/preprocessor/dec.hpp>
11?
12?#define?HELP_2(a?,?b)?a(b)
13?
14?#define?MEM_STRUCT_MAKE_IMPL(n)?template?<typename?_tlist>?\
15?struct?In?:?public?_str_impl_help<n>::template?In<typename?_tlist::Tail>?\
16?{?\
17?????typedef?_str_impl_help<n>::template?In<typename?_tlist::Tail>?_Base;?\
18?????enum?{????en_member_count?=?_Base::en_member_count+1,?};?\
19?????typedef?typename?::Loki::TL::TypeAt<_tlist,?0>::Result?_type##n;?\
20?????_type##n?m_P##n;?\
21?????__declspec(property(get?=?GetF##n,?put?=?PutF##n))?\
22?????_type##n?Field##n;?\
23?????_type##n?GetF##n()?{?return?m_P##n;?}?\
24?????void?PutF##n(const?_type##n?val)?{?m_P##n?=?val;?}?\
25?};?\
26?}
27?
28?#define?MEM_STRUCT_MAKE(n)?template?<>?\
29?????struct?_str_impl_help<n>?{?\
30?????HELP_2(MEM_STRUCT_MAKE_IMPL,?BOOST_PP_DEC(n))
31?????
32?
33?namespace?impl_help
34?{
35?????template?<int?_p>
36?????struct?_str_impl_help;
37?
38?????template?<>
39?????struct?_str_impl_help<0>?{};
40?????template?<>
41?????struct?_str_impl_help<1>?{
42?????????template?<typename?_tlist>?
43?????????struct?In?{
44?????????????enum?{
45?????????????????en_member_count?=?1,
46?????????????};
47?
48?????????????typename?::Loki::TL::TypeAt<_tlist,?0>::Result?m_P0;
49?
50?????????????__declspec(property(get=GetF0,?put=PutF0))
51?????????????typename?::Loki::TL::TypeAt<_tlist,?0>::Result?Field0;
52?
53?????????????typename?::Loki::TL::TypeAt<_tlist,?0>::Result?GetF0()?{?
54?????????????????return?m_P0;?
55?????????????}
56?
57?????????????void?PutF0(const?typename?::Loki::TL::TypeAt<_tlist,?0>::Result?val)?{
58?????????????????m_P0?=?val;
59?????????????}
60?????????};
61?????};
62?
63?????MEM_STRUCT_MAKE(2);
64?????MEM_STRUCT_MAKE(3);
65?????MEM_STRUCT_MAKE(4);
66?????MEM_STRUCT_MAKE(5);
67?????MEM_STRUCT_MAKE(6);
68?????MEM_STRUCT_MAKE(7);
69?????MEM_STRUCT_MAKE(8);
70?????MEM_STRUCT_MAKE(9);
71?????MEM_STRUCT_MAKE(10);
72?????MEM_STRUCT_MAKE(11);
73?????MEM_STRUCT_MAKE(12);
74?????MEM_STRUCT_MAKE(13);
75?????MEM_STRUCT_MAKE(14);
76?????MEM_STRUCT_MAKE(15);
77?}
78?
79?template?<typename?_tlist>
80?struct?struct_mem?:?public?impl_help::_str_impl_help<?::Loki::TL::Length<_tlist>::value?>::?
81?????template?In<?::Loki::TL::Reverse<_tlist>::Result?>
82?{
83?};
84?
85?
86?#endif?//!defined(INCLUDE_40697E96_B6DE_449d_A516_B0376650A488)

上面是模板實現根據指定typelist,生成擁有相應成員的結構.

typedef struct_mem< TYPELIST_6(DB_STRING, DB_STRING, DB_STRING, DB_STRING, DB_STRING, DB_STRING) > CustomerRow; 就可以聲明一個有6個成員的結構了.
上面的代碼使用template的特化到有15個成員的結構,全部寫出來的話,重復而且麻煩,所以使用了宏來幫助生成.


?

posted @ 2007-01-19 10:35 hdqqq 閱讀(1029) | 評論 (0)編輯 收藏

?:操作符是一個條件賦值的操作符號,常用來對變量進行條件賦值如:

int i = 1, j = 2;
int c_max = ( i > j ? i : j );

不過今天看了網上的一段代碼,是這樣用的

(i->second.left ? file.leechers : file.seeders)--;

上面的三個都是變量,也可以編譯通過,所以寫了段代碼試了一下

?1?void?show_1(int?val)
?2?{
?3?????cout?<<?"function?show_1?called!"?<<?endl;
?4?}
?5?
?6?
?7?void?show_2(int?val)
?8?{
?9?????cout?<<?"function?show_2?called!"?<<?endl;
10?}
11?
12?
13?void?quest_test()
14?{
15?????int?c?=?0;
16?????int?a?=?1,?b?=?2;
17?????(c++???a?:?b)--;
18?????cout?<<?a??<<?"?and?"??<<?b?<<?endl;
19?????(c???a?:?b)++;
20?????cout?<<?a??<<?"?and?"??<<?b?<<?endl;
21?????(c???show_1?:?show_2)(100);
22?}
23?
24?
25?最后的輸出是
26?1?and?1
27?2?and?1
28?function?show_1?called!


最怪的是?:操作符號,居然也可以用在函數上.

(c ? show_1 : show_2)(100);

其實等同于

if (c)
? show_1(100);
else
? show_2(100);

不過簡練了很多.

posted @ 2006-12-29 17:06 hdqqq 閱讀(1300) | 評論 (3)編輯 收藏

unix系統下的banner是用于顯示點陣字體的程序cygwin下有類似的程序可以在windows下跑,但是不支持中文.

所以自己寫了一個windows下的類似程序,自己建一個控制臺工程(需支持mfc)后,把下面的代碼復制一下就可以了.同時,新年快到了,祝大家:

???? #????? ##?????? ##??????????? #??? ##???????? #??? ####?
? ###### ###??????? #########????? # #?? #???????? #######???
??? # #? #??????? ##?? ##??????? # # ########????? #?? ##????
? ###### #######?? ##########??? # #???? #? #???? ##?? ##????
?#? ##? ## ## #??? ##? ##??????? # #???? ####???? ############
? ###### # ##??? ###############?? # ##########????? # ###???
?? ### ### ##??? ##??? ##? ####??? #??? # #? #????? ## ## ##?
? #### ##? ##????????? ##????????? #?? ## ##????? ###? ##? ####
?#? ##? #? ##????????? ##????????? # ###?? ##??? #?? # ##??? ##
??????????? #????????? ##????????? ##???????????????? ##??????

????? 8? 88??????????? 8?????????????? 8? 8??????????????? 88??
?? 8888888888???? 88888888888????? 88? 8 88?????? 88888??? 88??
????? 8? 8???????? 888888888?????? 8?? 8????????? 8 8 8 88888888
? 8888 888888?????? 8888888??????? 888888888????? 8 8 8??? 8888
???? 888? 88??????? 88?? 88?????????? 88888?????? 8 8 8?? 888??
?? 88? 8?? 888??????? 8888??????????? 88 88?????? 8 8 8? 8888??
8888 8 8888 888? 88888888888888???? 88? 88??????? 888 8888 88??
??? 8? 88 88 8????? 88888888???? 8888? 88 888????? 8888??? 88??
?? 8 888 8 8??????? 88??? 88??????? 8888?? 8888? 888? 88 8888??
????? 88??????????? 88888888???????????????? 8???????????? 8???

使用方式

wbanner [-c 填充字符] [-f 字體名稱] [-s 字體大小] 顯示文本

/////////////////

// ?wbanner_6.cpp?:?Defines?the?entry?point?for?the?console?application.
//

#include?
" stdafx.h "
#include?
" wbanner_6.h "

#ifdef?_DEBUG
#define ?new?DEBUG_NEW
#undef ?THIS_FILE
static ? char ?THIS_FILE[]? = ?__FILE__;
#endif

/////////////////////////////////////////////////////////////////////////// //
// ?The?one?and?only?application?object

CWinApp?theApp;

using ? namespace ?std;


#define ?BMP_WIDTH????100
#define ?BMP_HEIGHT????30

void ?ParseArg(CString & ?info,?CString & ?fill_str,CString & ?font_name,? int & ?font_size,? int ?argc,TCHAR * ?argv[])
{
????
int ?i;
????
for ?(i? = ? 1 ;?i? < ?argc;?i ++ )?{
????????
if ?(strcmp(argv[i],? " -c " )? == ? 0 ? && ?i? < ?argc)?{
????????????fill_str?
= ?argv[ ++ i];
????????????
continue ;
????????}
????????
if ?(strcmp(argv[i],? " -f " )? == ? 0 ? && ?i? < ?argc)?{
????????????font_name?
= ?argv[ ++ i];
????????????
continue ;
????????}
????????
if ?(strcmp(argv[i],? " -s " )? == ? 0 ? && ?i? < ?argc)?{
????????????font_size?
= ?atoi(argv[ ++ i]);
????????????
if ?(font_size? <= ? 120 )?
????????????????font_size?
= ? 120 ;
????????????
continue ;
????????}

????????info?
= ?argv[i];
????????
break ;
????}
}

void ?ShowBanner(LPCTSTR?fill_str,?LPCTSTR?info,?LPCTSTR?font_name,? int ?font_size)
{
????CFont?lfont;
????CDC?ldc;
????CBitmap?lbmp;
????ldc.CreateCompatibleDC(NULL);
????lbmp.CreateCompatibleBitmap(
& ldc,?BMP_WIDTH,?BMP_HEIGHT);
????CBitmap
* ?pold? = ?(CBitmap * )ldc.SelectObject( & lbmp);
????
????lfont.CreatePointFont(font_size,?font_name,?
& ldc);
????
????CFont
* ?poldfont? = ?(CFont * )ldc.SelectObject( & lfont);
????
????CRect?lrect(
0 ,? 0 ,?BMP_WIDTH,BMP_HEIGHT);
????
????ldc.FillSolidRect(
0 , 0 ,?BMP_WIDTH,?BMP_HEIGHT,?RGB( 255 , 255 , 255 ));
????ldc.DrawText(info,?
& lrect,?DT_LEFT);
????
????BITMAP?bmp_head;
????
????lbmp.GetBitmap(
& bmp_head);
????
????
????DWORD?bufsize?
= ?bmp_head.bmWidthBytes * bmp_head.bmHeight;
????
char * ?buf? = ? new ? char [bufsize];
????
????memset(buf,?
0 ,?bufsize);
????
????DWORD?get_ret?
= ?lbmp.GetBitmapBits(bufsize,?( void * )buf);
????
????
int ?i,j;
????
if ?(get_ret? != ? 0 )?{
????????
char ?ret[ 2 ]? = ?{? 13 ,? 10 };
????????CString?
out [ 2 ]? = ?{fill_str,? " ? " };
????????
for ?(i? = ? 0 ;?i? < ?bmp_head.bmHeight;?i ++ )
????????{
????????????
int ?charcount? = ? 0 ;
????????????
for ?(j? = ? 0 ;?j? < ?bmp_head.bmWidth;?j ++ )?{
????????????????
int ?offset? = ?bmp_head.bmWidthBytes * i + j / 8 ;
????????????????
char ?cur;
????????????????cur?
= ?buf[offset];
????????????????
char ?tt? = ?cur? & ?( 0x80 ? >> ?(j? % ? 8 ));
????????????????CString?temp;
????????????????
if ?(tt? == ? 0 )?{
????????????????????temp?
= ? out [ 0 ];
????????????????}
else ?{
????????????????????temp?
= ? out [ 1 ];
????????????????}
????????????????cout?
<< ?(LPCTSTR)temp;
????????????????charcount
++ ;
????????????}
????????????cout?
<< ?endl;
????????}
????}
????????
????ldc.SelectObject(pold);
????ldc.SelectObject(poldfont);
????delete?[]?buf;
}

void ?PrintUsage( int ?argc,?TCHAR * ?argv[])
{
????cout?
<< ? " not?enough?arguments " ? << ?endl;
????cout?
<< ? " Usage: " ? << ?endl;
????cout?
<< ?argv[ 0 ]? << ? " ?[-c?#]?[-f?font_name]?[-s?font_size]?A?string?to?print " ? << ?endl;
}

int ?_tmain( int ?argc,?TCHAR * ?argv[],?TCHAR * ?envp[])
{
????
int ?nRetCode? = ? 0 ;

????
// ?initialize?MFC?and?print?and?error?on?failure
???? if ?(AfxWinInit(::GetModuleHandle(NULL),?NULL,?::GetCommandLine(),? 0 ))
????{
????????
// ?TODO:?change?error?code?to?suit?your?needs

????????CString?info?
= ? " wbanner " ;
????????CString?font_name?
= ? " 宋體 " ;
????????CString?fill_str?
= ? " # " ;
????????
int ?font_size? = ? 120 ;
????????
????????
????????
if ?(argc? < ? 2 )?{
????????????PrintUsage(argc,?argv);
????????}
else ?{
????????????ParseArg(info,?fill_str,?font_name,?font_size,?argc,?argv);
????????????ShowBanner(fill_str,?info,?font_name,?font_size);
????????}
????}
else ?{
????????cerr?
<< ?_T( " Fatal?Error:?MFC?initialization?failed " )? << ?endl;
????????nRetCode?
= ? 1 ;
????}
????
return ?nRetCode;
}


posted @ 2006-12-22 10:13 hdqqq 閱讀(1173) | 評論 (2)編輯 收藏

? 今天寫了一個ace 的proactor的測試程序,代碼是在windows下編輯的,在windows下測試成功后,將代碼傳到一臺linux機器上進行測試,配置了相關的configure.in和Makefile.am文件后,用autoconf,automake和configure生成makefile然后make開始編譯,但是程序報錯,開始以為是ace的配置的問題,重新設置了ace的linux下的配置頭文件,并重新編譯,不行,然后重新設置configure.in文件和Makefile.am文件,還是不行,搞了半天,最后仔細看了gcc的報錯信息,是有一些頭文件無法包含,看了編譯的參數, incldue設置正確, 最后終于發現,原來是因為在windows下編輯的代碼,頭文件用了小寫名稱,導致在linux下包含的頭文件找不到,這個是在類unix下開發應該注意的小細節,一個疏忽,往往容易陰溝里翻船.特此記錄一下.
posted @ 2006-12-11 16:44 hdqqq 閱讀(737) | 評論 (0)編輯 收藏

????? 今天在網上下載了一個c++的代碼,項目文件是sln的文件.
我雙擊打開,vs2003報告說,這個項目文件是高版本的vs生成的,目前不支持,搞了半天這個項目文件是vs2005生成的,這種高級貨我當然沒用過,裝vs2005或者重新構建項目工程都比較麻煩,所以從項目文件上著手,看看是否可以修改一下,讓我的vs2003可以用. 隨便找了一個vs2003生成的sln文件,和vs2005生成的看看,都是類似xml的文件,差別只是一個版本號不同,把兩個文件修改為vs2003的8.0 sln版本,vs2003還是不認.估計是vcproj的差別,然后查看2003和2005vcproj文件的差別,也差不多,只是版本號上的差別,所以想辦法實驗了一下, 把 vs2005的sln文件刪除,用文本編輯程序打開vcproj文件,vs2005生成的文件,版本號是8,00 我直接改成了vs2003的7.10 然后保存vcproj文件,再雙擊打開,vs2003通過了,可以直接編譯運行了,vs2003還會自動生成新的sln文件.
posted @ 2006-12-09 00:27 hdqqq 閱讀(2455) | 評論 (0)編輯 收藏

;一個匯編版本的 hello world
;test.asm
;a hello world program with asm
.386P
.model FLAT

include listing.inc

INCLUDELIB LIBCD
INCLUDELIB OLDNAMES

PUBLIC _main
PUBLIC szHelloWorld
EXTERN _printf:NEAR


CONST SEGMENT
?szHelloWorld DB 'Hello World!', 0aH, 00H
CONST ENDS

_TEXT SEGMENT

_argc$ = 8
_argv$ = 12
_main PROC NEAR
?push OFFSET FLAT:szHelloWorld
?call _printf
?add esp, 4
?xor eax, eax?
?ret 0
_main ENDP
_TEXT ENDS

END
?
;編譯命令
;ml.exe??? /c?? /coff??? test.asm
;link /out:test.exe /subsystem:console kernel32.lib test.obj

posted @ 2006-09-21 14:25 hdqqq 閱讀(390) | 評論 (0)編輯 收藏

STL, Loki,Boost Functor 比較之 Boost ( )

?????? 在這一部分中 , 要討論的是 Boost 庫中的 Function 的有關功能 , 于前面兩篇不同的是 ,Boost 庫的規模相對于 Loki STL 來說 , 在規模上大了很多 , 這篇文章中討論的是 boost 中的 functor 部分 , 寫的不好之處 , 歡迎提出意見 . 寫作本文使用的是 Boost 1_33_1 版本 , 同時參考了 Boost 文檔的 function 部分的說明 .

?

寫在前面

Boost Function 功能中 , 用到了 Boost Preprocessor, 在這部分中 Boost 提供的宏預處理功能是很強大的 , 主要的宏功能有 重復生成 (BOOST_PP_REPEAT_FROM_TO), 條件判斷 (BOOST_PP_IF), 連接 (BOOST_PP_CAT), 數值比較 (BOOST_PP_GREATER), 參數枚舉 (BOOST_PP_ENUM_PARAMS) , 使用這些宏 , 可以按照自己的需要用宏生成模板類或者代碼 , 實在是一個很有效而且很創新的功能 , 可以說把預處理器的功能用到了登峰造極的地步 . 不過 , 代價是要花更多的時間在編譯上 , 我有一個 18000 行代碼的工程 , 在一個頭文件中使用了 Preprocessor 產生一些模板代碼后 , 編譯時間從原先的 4 分鐘一下子升到了 8 分多秒 ( 我的機器比較老 ), 最后不得不寫了個功能 Proxy , 隔絕 cpp 文件對該頭文件的依賴關系才縮短了編譯時間 .

TypeTraits typetraits 的功能是在給定一個數據類型后 , 通過 c++ 的模板能力 , 來取得這個關于這個數據類型的相關信息 . Loki 庫中 , 也提供了 TypeTrait 功能 . 常用的有 判斷是否為指針 , 判斷是否為常量 , 判斷是否為引用 , 判斷是否為數值等 . 在創建模板類或者函數的時候 , 有時候需要根據模板參數的類型對模板進行特化 , 這是一個很重要的輔助功能 ,boost 中也有 typetrait 功能 , functor 生成的過程中 , 也使用了一些 typetrait 的功能 .

?

?

Boost 的的 Functor 的頭文件位于 <boost/function.hpp> 文件中 , 有一個很重要的宏

BOOST_FUNCTION_MAX_ARGS 用于 定義 boost 的預處理器展開的 Functor 最多的參數個數 , 缺省的定義為

#define ? BOOST_FUNCTION_MAX_ARGS ? 10

如果有需要擴充 Functor 的參數個數 , 可以在包含 Boost Functor 頭文件之前 , 自己定義這個宏的數值 , 但是 , 最多可以到 50, 超過這個數值后 , 需要手工修改 <boost/function/detail/maybe_include.hpp> 中的代碼 , Functor 可以使用的參數再進行擴充 .

?

Boost Functor 的展開

?????? Boost 中使用了預處理元編程提供的疊代頭文件的功能 , 反復疊代 <boost/function/function_template.hpp>, 最終生成使用所需要的模板類

?

boost::function < 返回值 ( 參數 [, 參數 ]…)>, 用戶可以使用編譯器的 /P( 微軟 c++ 編譯器 ),? -save-temps(gcc 編譯器 ) 開查看宏展開后的文件 .

?

?

?

有關 STL Loki 中的 Functor 的前面兩篇位于我的另外一個 blog

http://blog.csdn.net/hdqqq/archive/2006/02/07/593877.aspx

http://blog.csdn.net/hdqqq/archive/2006/01/25/588348.aspx

posted @ 2006-09-13 21:39 hdqqq 閱讀(3981) | 評論 (1)編輯 收藏

/*
?這幾天在編譯firefox,順便學一下unix下的shell的腳本編寫,unix下的管道和工具
結合起來用的話,功能確實強大.寫了個測試的腳本,功能是把c/cpp/h文件中所有包含的頭文件
找出來,支持通配符.
?可以把下面的文字復制到某個文件,然后另存為.sh后綴的文件放到/bin目錄下就可以運行了,在
cygwin環境下測試通過.
*/

## list_head.sh

ARR_NUM=1

if [ $# -lt $ARR_NUM ]
then
echo "使用方式:"
echo "$0 文件名"
echo "文件名: C/CPP/H 文件 或 通配符 *.c(*.cpp)"
else

cat $@ | grep include | grep \# | sort | uniq | awk -Finclude '{ print $2 }' | tr -d \" | tr -d \' | tr -d \< | tr -d \> | sort | uniq | awk '{ print $1 }'

fi

exit 0

posted @ 2006-09-06 17:18 hdqqq 閱讀(489) | 評論 (0)編輯 收藏

前幾天心血來潮 , 想自己編譯一個 firefox 試試看 , 折騰了好幾天 , 終于完成了 .

寫篇文章總結一下 .

我編譯的環境 :

1.?????? VC6 + sp5

2.?????? firefox 編譯需要的輔助工具 wintools.zip

3.?????? cygwin 環境

?

準備工作 :

1.???????下載 firefox 程序代碼,在 mozilla 的站點上可以下載到,我編譯的是 firefox 1.5.0.6 版本

2.?????? 下載編譯需要的 wintools.zip 工具 ,1.73MB 大小 , 其中帶有 glib libidl , 在下載解壓縮后 , 建立一個環境變量 MOZ_TOOLS 到某個目錄 , 然后進入解壓縮后的 windows 目錄 , 運行 install.bat 文件 , 安裝相關需要的文件 .

3.?????? 安裝 cygwin 環境 , 一個 window 下的類 unix 平臺 , 這里需要注意的是 , 最新的 cygwin , 安裝的 make 版本是 3.81 , 而編譯 firefox 需要的是 3.80 版本的 make, 解決的方法是到 cygwin 的某個 ftp 鏡像站點上去下一個 3.80 版本的文件 , 安裝到 cygwin 安裝目錄下的 /bin 目錄下就可以了 .

其中編譯 firefox 需要的基本工具

ash -- UNIX-like command line interpreter shell (Base category)

coreutils -- GNU core utilities (includes fileutils, install, sh-utils, and textutils) (Base category)

cvs -- concurrent versions system (Devel category)

diffutils -- file comparison utility (Base category)

findutils (Base category)

gawk -- pattern matching language (Base and Interpretors categories)

grep -- text search tool (Base category)

libiconv -- character set conversion (Devel category)

make 3.80 (not 3.81!) -- dependency analyzer for software builds (Devel category)

patchutils -- a small collection of programs that operate on patch files (Devel category)

perl -- a scripting language used to control parts of the build (Interpreters category)

sed -- a search and replace language (Base category)

unzip -- zip file extraction (Archive category)

zip -- zip file creation (Archive category)

可以在 cygwin 命令窗口中輸入相關命令檢測是否安裝了相關的程序 ., 其實如果下載了 firefxo 源代碼的話 , cvs 中的都不是必須的 .

4.?????? 安裝 vc6 + sp5, 編譯 firefox 1.5.0.6, 推薦的是 vc6 cpp 編譯器 . vs6 安裝后 , 會自動設置相關的 path,include lib 環境變量 . 有一個需要注意的是 , vc6 link.exe cygwin 中的 link.exe 是相同的名字 , 為了避免在編譯的時候 , 調用錯誤的 link 執行文件 , 可以把 cygwin/bin 中的 link.exe 改名為 glink.exe 避免沖突 . Vs sp5 補丁也需要打一下 , 否則 , 生成的 xpldl.exe(firefox 用來編譯 idl 文件的工具 ) 在編譯 idl 過程中會報錯 .

5.?????? 配置文件

在環境和編譯工具準備好后 , 解壓縮 firefox 的代碼 , 然后在 firefox 代碼目錄的 mozilla 目錄下 , 建立一個名為 .mozconfig 的文件 , 并在其中編輯文本

. $topsrcdir/browser/config/mozconfig

ac_add_options --enable-optimize

ac_add_options --disable-debug

ac_add_options --enable-static

ac_add_options --disable-shared

ac_add_options --disable-test

開工

上面所有工作完成之后 , 啟動 cygwin 命令窗口 , 進入 firefox 代碼的 mozilla 目錄

輸入 make –f client.mk build 命令開始編譯 , 一切順利的話 , 幾十分鐘后 , 就會有一個 firefox 的執行文件生成到 mozilla/dist/bin 目錄下 .

需要注意的是 , 在生成一個 test 的模塊的時候 , 會報一個 jsint 類型未定義 , 這個無關緊要 , 因為 firefox 已經生成了 , 這是一個測試模塊 , 我的解決方法是 ,?打開那個出錯的cpp文件,加入

#ifdef?? _MSCVER

typedef? int? int32;

#endif

然后再編譯就可以了 , 所謂自動動手 , 豐衣足食 , 有的時候 , 實在不行的話 , 需要把 firefox 的代碼自己動手改一下 .

?

?

posted @ 2006-09-03 18:14 hdqqq 閱讀(1602) | 評論 (0)編輯 收藏

僅列出標題
共4頁: 1 2 3 4 
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            狠狠色综合播放一区二区| 久久裸体艺术| 国产精品豆花视频| 亚洲视屏在线播放| 亚洲午夜国产成人av电影男同| 欧美日韩一区二区在线播放| 亚洲午夜久久久| 午夜日韩激情| 在线视频观看日韩| 亚洲精品在线电影| 国产精品久久97| 久久精品综合| 欧美1区3d| 亚洲欧美国产视频| 久久精品国产欧美激情| 亚洲日韩欧美视频| 国产精品99久久久久久久久| 国产一区二区电影在线观看| 欧美韩国日本一区| 国产精品xvideos88| 久久精品国产久精国产爱| 久久偷看各类wc女厕嘘嘘偷窃| 亚洲最新合集| 欧美在线播放高清精品| 亚洲精品综合在线| 性欧美1819性猛交| 亚洲伦理在线观看| 久久电影一区| 亚洲视频一区在线观看| 久久国产福利国产秒拍| 野花国产精品入口| 久久九九99| 午夜精品一区二区三区在线播放| 久热re这里精品视频在线6| 亚洲无玛一区| 欧美顶级少妇做爰| 久久婷婷蜜乳一本欲蜜臀| 欧美日韩色一区| 暖暖成人免费视频| 国产日本欧美一区二区三区| 免费欧美视频| 亚洲国产精品一区二区尤物区| 亚洲欧洲精品一区二区三区 | 夜色激情一区二区| 久久九九免费| 久久国产精品72免费观看| 欧美日产国产成人免费图片| 美女国内精品自产拍在线播放| 国产精品国产自产拍高清av| 欧美激情欧美狂野欧美精品| 国产亚洲网站| 亚洲欧美网站| 亚洲综合欧美日韩| 欧美日韩精品一区| 亚洲精品一二| 99v久久综合狠狠综合久久| 久久亚洲春色中文字幕| 久久久女女女女999久久| 国产精品午夜在线观看| 亚洲美女视频在线观看| 亚洲美女黄色| 欧美极品一区| 亚洲伦理自拍| 亚洲视频axxx| 国产精品美女视频网站| 亚洲手机视频| 欧美一级专区免费大片| 国产精品视频专区| 亚洲一区日韩在线| 欧美夜福利tv在线| 国产一区二区三区电影在线观看 | 亚洲片在线观看| 99国产精品久久久| 欧美chengren| 亚洲美女精品久久| 亚洲欧美国产日韩中文字幕| 国产女主播在线一区二区| 欧美在线日韩在线| 免费欧美在线| 亚洲视频你懂的| 国产精品中文字幕欧美| 欧美在现视频| 亚洲区第一页| 欧美一区久久| 亚洲国产精品成人一区二区 | 国产日韩精品一区观看| 久久狠狠亚洲综合| 欧美激情欧美狂野欧美精品| 在线亚洲成人| 国产亚洲欧美日韩日本| 另类尿喷潮videofree | 亚洲韩国精品一区| 亚洲一区二区久久| 国产综合色精品一区二区三区| 久久久久国产免费免费| 亚洲精品免费电影| 欧美一区二区三区免费大片| 在线免费观看视频一区| 欧美日韩成人精品| 久久福利影视| 亚洲美女视频在线免费观看| 久久久久国产精品厨房| 国产日韩欧美三区| 先锋影音国产一区| 亚洲二区精品| 国产精品a级| 猛干欧美女孩| 亚洲欧美精品在线| 亚洲国产精品久久久久秋霞不卡| 亚洲欧美日韩一区在线| 亚洲国产精品99久久久久久久久| 国产精品国产成人国产三级| 裸体歌舞表演一区二区| 亚洲欧美日韩国产综合在线 | 最近看过的日韩成人| 久久国产色av| 在线亚洲欧美| 亚洲欧洲在线观看| 红杏aⅴ成人免费视频| 欧美三级网址| 欧美激情自拍| 另类激情亚洲| 久久久蜜桃精品| 欧美在线不卡视频| 亚洲自拍都市欧美小说| 99精品欧美一区| 亚洲国产美国国产综合一区二区| 久久久久亚洲综合| 欧美一区在线看| 午夜精品久久| 亚洲综合99| 亚洲一区网站| 夜夜爽99久久国产综合精品女不卡| 极品尤物av久久免费看| 国产综合激情| 国产综合香蕉五月婷在线| 国产乱人伦精品一区二区 | 日韩一本二本av| 亚洲国产欧美一区| 在线视频国产日韩| 在线看日韩欧美| 亚洲国产日日夜夜| 亚洲国产精品ⅴa在线观看| 亚洲国产精品视频一区| 在线观看亚洲视频| 亚洲国产另类 国产精品国产免费| 国产午夜精品理论片a级大结局| 国产欧美日韩麻豆91| 国产免费成人在线视频| 国产一区91| 激情视频一区二区三区| 亚洲第一二三四五区| 亚洲成色www8888| 日韩视频精品在线| 中国女人久久久| 欧美一激情一区二区三区| 久久久久久国产精品mv| 久久青草福利网站| 欧美激情一区| 99视频精品在线| 午夜欧美大尺度福利影院在线看| 亚洲自拍偷拍福利| 久久蜜桃av一区精品变态类天堂| 蜜桃av一区二区| 欧美日韩美女在线| 国产日韩亚洲| 最新国产成人av网站网址麻豆| aa级大片欧美三级| 欧美一区二区三区在线免费观看| 久久国产精品一区二区| 欧美本精品男人aⅴ天堂| 亚洲精品乱码久久久久久久久| 日韩亚洲欧美成人一区| 欧美一级电影久久| 欧美mv日韩mv亚洲| 国产伦精品一区二区三区高清| 一区二区三区四区精品| 亚洲日本aⅴ片在线观看香蕉| 亚洲视频图片小说| 久久久久久久综合| 欧美性大战久久久久久久蜜臀 | 欧美日韩爆操| 国产主播一区二区| 亚洲午夜久久久久久久久电影院 | 欧美激情自拍| 亚洲影院在线观看| 欧美成人国产| 国产一区二区毛片| 在线中文字幕一区| 欧美wwwwww| 欧美亚洲三区| 国产精品国产自产拍高清av王其| 亚洲高清在线观看| 久久激情一区| 一区二区三区高清视频在线观看| 开心色5月久久精品| 国产欧美一区二区精品性| 在线视频你懂得一区二区三区| 久久综合给合久久狠狠色| 亚洲婷婷综合久久一本伊一区|