以前看過很多關于設計模式的書籍,但是沒怎么用過,都想過眼煙云一般,煙消云散了,在我的腦海里無影無蹤了。
近期有開始看起,想想這方面還是蠻重要的,抱著HeadFirst看起來了,不過是影印版,也權當一塊練英語了。加油!
發現,如果不寫出來,知識擺在那里依舊是死的知識,不能活躍在自己的腦海里。所以借此一角,發發我的小感知。
posted @
2009-06-29 18:48 Sandy 閱讀(202) |
評論 (0) |
編輯 收藏
今天解決了兩個BUG,但是原因都是自身的原因。
第一個BUG是由于修改,一份代碼發生了變化,另一份代碼沒有相應進行變化,導致了BUG的發生。可能你也很好奇為什么有兩份代碼呢?一個是加長版,一個是縮減版。主要是另一個地方只用到了一個功能,而這個功能又牽涉了一些小函數,都搬過去感覺有些臃腫。但是不搬過去就存在了這種情況,兩個代碼不統一。
不知道怎么解決這個情況,也只能維持現狀,保持兩段代碼了。不過需要人為的維護代碼了。
第二個BUG主要是細心的問題吧。new很隱蔽,導致沒有釋放,這樣造成了內存泄露,進而引發了數據讀取的異常。這個類似的BUG見過一些了。內存泄露還是一個值得注意的大問題。所以要好好檢查一下代碼。
就寫這么多吧。
posted @
2009-06-29 18:44 Sandy 閱讀(171) |
評論 (0) |
編輯 收藏
1、接口類似于類,但接口的成員都沒有執行方式,它只是方法、屬性、事件和索引符的組合而已,并且也只能包含這四種成員;類除了這四種成員之外還可以別的成員(如字段)。
2、不能實例化一個接口,接口只包括成員的簽名;而類可以實例化(abstract類除外)。
3、接口沒有構造函數,類有構造函數。
4、接口不能進行運算符的重載,類可以進行運算符重載。
5、接口的成員沒有任何修飾符,其成員總是公共的,而類的成員則可以有修飾符(如:虛擬或者靜態)。
6、派生于接口的類必須實現接口中所有成員的執行方式,而從類派生則不然。
那么為什么還要有接口呢?
主要原因是它是一種有效的契約。類有一些成員,不考慮把這些成員組合在一起,類只是一個擁有各種方法、字段和屬性的列表,但為了能以某種方式使用類,必須知道類能執行那些功能,具體的操作就是聲明執行一個或多個接口的類,類執行接口的方式是從接口中派生,再提供這個接口中定義的所有成員的執行方式。
摘自:
http://www.cnblogs.com/ajayumi/archive/2008/06/10/1216746.html
posted @
2009-06-26 17:32 Sandy 閱讀(253) |
評論 (0) |
編輯 收藏
摘自:
http://www.cnblogs.com/randylee/archive/2007/07/19/824555.html
WM5以前的系統中一般都是使用的CEDB數據庫,EDB是WM5中的新特性之一。為了改善應用程序的性能和長期可移植性,CEDB 已經被 EDB 所取代。EDB 利用了 SQL Mobile 使用的存儲子系統,并且提供了明顯優于 CEDB 的性能(尤其是在與持久存儲區一起使用時)。因為 CEDB 提供了與 EDB 完全相同的函數集 ,所有函數都具有相同的名稱和參數列表。但是EDB中也包含了CEDB中所沒有函數,并且創建方法也不相同了,要比CEDB復雜。以下就是EDB的創建和使用法:
一。創建:
1。CeMountDBVol( );//創建卷
2。CeCreateDatabaseWithProps();//卷創建成功后創建EDB
3。CeCreateSession();//EDB創建成功后創建session,用于打開EDB
4。CeOpenDatabaseInSession();//打開EDB
創建EDB時前還要創建一個CEDBASEINFOEX對象,這個對象用于創建EDB中的info,用于設定EDB。
在打開時還要維護一個全局的HANDLE,在以后的操作中是要使用的
二。選擇數據
1。CeSeekDatabaseEx();//定位所要找的數據
2。CeReadRecordPropsEx();//讀出定位的數據
創建一個CEPROPVAL對象,將所要定位數據的條件傳給這個結構。
三。插入數據
CeWriteRecordProps();//數據寫入EDB
創建一個CEPROPVAL對象,或對象數組,將所要寫入的數據傳給這些對象。
四。刪除數據
1。CeSeekDatabaseEx();//定位要刪除的數據
2。CeDeleteRecord();//刪除定位的數據
五。更新數據
所插入數據基本相同,就是將已有數據覆蓋
1。CeSeekDatabaseEx();//定位所要找的數據
2。CeWriteRecordProps();//數據寫入新數據到EDB覆蓋原數據
六。關閉EDB
CloseHandle(打開時的句柄);
在這里關鍵是創建EDB時所選的參數,和對結構體的使用,這樣才能正確定位數據,否則選擇、更新、刪除都無法實現。
另外, MSDN中也有相關的文章
EDB Database Support
http://msdn.microsoft.com/en-us/library/ms885373.aspx
一定要理解的清楚一些。
呵呵,加油。
posted @
2009-06-26 13:48 Sandy 閱讀(956) |
評論 (0) |
編輯 收藏
現在做的這個項目,需求總是不停的變,稀稀拉拉做了很長時間了。
最近終于快做完了,感覺有一個就是讓自己能夠以不變應萬變,寫一個可擴展的接口,能夠應對各種不同的變化。
可擴展性,就要有前瞻性,這是我一個同事的口頭禪,要有前瞻性,你能預測到這一點。
想想也很有道理。
所以寫程序的時候,不要簡單的為實現功能而實現,要考慮程序的可擴展性。
posted @
2009-06-25 17:49 Sandy 閱讀(206) |
評論 (0) |
編輯 收藏
寫的程序還是有很多問題的,慢慢積累經驗,積攢一些調試和修改BUG的經驗,對以后還是很有裨益的。
看著改掉的一個個BUG,心里還是很有成就感的。
呵呵,繼續加油。
雖然最近加班多一些,但是努力哈,就快看到黎明了,這只是最黑暗的時刻而已。
posted @
2009-06-23 21:02 Sandy 閱讀(206) |
評論 (0) |
編輯 收藏
今天一直很疑惑手機的語言,其實是對API函數GetSystemDefaultLCID的不解。
今天在實際中終于摸清楚了該值是怎么一回事,原來他取得是設置中區域設置中的語言標號,而非手機界面的語言標號。
怎么判斷呢?
我是通過下面的方式進行的。
LCID lcid = GetSystemDefaultLCID();
WORD PriLan = PRIMARYLANGID(lcid);
WORD SubLan = SUBLANGID(lcid);

switch (PriLan)

{
case LANG_CHINESE:

{
if (SubLan == SUBLANG_CHINESE_SIMPLIFIED)

{
MessageBox(GetForegroundWindow(), _T("simple chs"), _T("note"), MB_OK);
}
else if (SubLan == SUBLANG_CHINESE_TRADITIONAL)

{
MessageBox(GetForegroundWindow(), _T("traditional chs"), _T("note"), MB_OK);
}
}
break;

case LANG_ENGLISH:

{
MessageBox(GetForegroundWindow(), _T("English"), _T("note"), MB_OK);
}
break;
default:

{
MessageBox(GetForegroundWindow(), _T("others"), _T("note"), MB_OK);
}
break;
}
這個有什么作用呢?Mobile手機更改語言設置后,其實對手機顯示的語言沒有多大影響,只是提示框框,菜單什么的可能會出現指定的文字,排版什么的按這種語言。
那么界面顯示的語言怎么獲得呢?利用GetUserDefaultUILanguage,判斷方式可同上。
不錯吧!
posted @
2009-06-18 16:38 Sandy 閱讀(373) |
評論 (0) |
編輯 收藏
對于成員初始化列表,熟悉有不是很熟悉。什么情況下使用呢?心里還是發怵,說不出所以然來。
學習是王道,搜索是方法。有了網絡就是好。
摘自:
http://www.cnblogs.com/heyutao/archive/2009/05/22/1487081.html成員初始化列表 類對象的構造順序是這樣的:
1.分配內存,調用構造函數時,隱式/顯示的初始化各數據成員
初始化階段可以是顯式的或隱式的,取決于是否存在成員初始化表。隱式初始化階段按照聲明的順序依次調用所有基類的缺省構造函數,然后是所有成員類對象的缺省構造函數。
2.進入構造函數后在構造函數中執行一般計算
計算階段由構造函數體內的所有語句構成。在計算階段中,數據成員的設置被認為是賦值,而不是初始化。
使用初始化列表有兩個原因:
1.必須這樣做:
三種情況下需要使用初始化成員列表
1)對象成員;
2)const修飾的成員;
3)引用成員數據;
(1)如果有一個類成員,它本身是一個類或者是一個結構,而且這個成員它只有一個帶參數的構造函數,而沒有默認構造函數,這時要對這個類成員進行初始化,就必須調用這個類成員的帶參數的構造函數,如果沒有初始化列表,那么他將無法完成第一步,就會報錯。
using namespace std;
class ABC


{
public:

ABC(int x,int y,int z):a(x),b(y),c(z)
{};
private:
int a;
int b;
int c;
};
class MyClass


{
public:

MyClass(int a,int b,int c):abc(a,b,c)
{}
private:
ABC abc;
};

int main()


{
MyClass o(1,2,3);
return 0;
}
(2)當類成員中含有一個const成員時
(3)當類成員中含有一個引用時
#include<iostream>
using namespace std;


class ConstRef
{
public:
ConstRef(int i);
void print();
private:
int a;
const int b;//const成員
int &c;//引用
};

ConstRef::ConstRef(int i):b(i),c(a)//含有一個const對象時,或者是一個引用時使用初始化成員列表


{
a = i; // ok
//b = i; // 錯誤
//c = a; // 錯誤
}
void ConstRef::print()


{
cout<<a<<endl;
cout<<b<<endl;
cout<<c<<endl;
}
int main()


{
ConstRef o(1);
o.print();
return 0;
}
2.效率要求這樣做:
類對象的構造順序顯示,進入構造函數體后,進行的是計算,是對他們的賦值操作,顯然,賦值和初始化是不同的,這樣就體現出了效率差異,如果不用成員初始化列表,那么類對自己的類成員分別進行的是一次隱式的默認構造函數的調用,和一次復制操作符的調用,如果是類對象,這樣做效率就得不到保障。
注意:構造函數需要初始化的數據成員,不論是否顯式的出現在構造函數的成員初始化列表中,都會在該處完成初始化,并且初始化的順序和其在聲明時的順序是一致的,與列表的先后順序無關,所以要特別注意,保證兩者順序一致才能真正保證其效率。
現在明白為什么要使用成員初始化列表了。
這里再強調一下類的初始化的順序,應該是類成員變量的初始化不是按照初始化表的順序被初始化的,而是按照在類中聲明的順序被初始化的。
這是摘自:Effective C++學習筆記:初始化列表中成員列出的順序和它們在類中聲明的順序相同 http://www.shnenglu.com/xczhang/archive/2008/01/22/41613.html
為什么會這樣呢?我們知道,對一個對象的所有成員來說,它們的析構函數被調用的順序總是和它們在構造函數里被創建的順序相反。那么,如果允許上面的情況(即,成員按它們在初始化列表上出現的順序被初始化)發生,編譯器就要為每一個對象跟蹤其成員初始化的順序,以保證它們的析構函數以正確的順序被調用。這會帶來昂貴的開銷。所以,為了避免這一開銷,同一種類型的所有對象在創建(構造)和摧毀(析構)過程中對成員的處理順序都是相同的,而不管成員在初始化列表中的順序如何。
注意:上述內容不適用于static變量,static變量應該在類的構造函數前被初始化。
好文章拿來學習,請作者見諒哈!
posted @
2009-06-18 13:33 Sandy 閱讀(459) |
評論 (0) |
編輯 收藏
對于拷貝構造函數引用傳遞,似乎司空見慣,認為理所當然。但是被問起這個問題,的確是一片茫然,為什么呢?
去網上搜索了一下,的確有很多這方面的知識講解。
我們先看一下CSDN上的一個帖子的回答:
簡單的回答是為了防止遞歸引用。
具體一些可以這么講:
當一個對象需要以值方式傳遞時,編譯器會生成代碼調用它的拷貝構造函數以生成一個復本。如果類A的拷貝構造函數是以值方式傳遞一個類A對象作為參數的話,當需要調用類A的拷貝構造函數時,需要以值方式傳進一個A的對象作為實參; 而以值方式傳遞需要調用類A的拷貝構造函數;結果就是調用類A的拷貝構造函數導致又一次調用類A的拷貝構造函數,這就是一個無限遞歸。
這個解釋還是蠻具體的。
利用值傳遞的話,會導致遞歸引用。
還有一片文章也談到了這個問題, 我覺得寫得也非常好!
為什么拷貝構造函數必須為引用傳遞,不能是值傳遞? 鏈接地址:
http://www.cnblogs.com/chio/archive/2007/09/14/893299.html其中講到了3個問題
1是拷貝構造函數的作用。
作用就是用來復制對象的,在使用這個對象的實例來初始化這個對象的一個新的實例。
2是參數傳遞過程到底發生了什么?
將地址傳遞和值傳遞統一起來,歸根結底還是傳遞的是"值"(地址也是值,只不過通過它可以找到另一個值)!
i)值傳遞:
對于內置數據類型的傳遞時,直接賦值拷貝給形參(注意形參是函數內局部變量);
對于類類型的傳遞時,需要首先調用該類的拷貝構造函數來初始化形參(局部對象);如void foo(class_type obj_local){}, 如果調用foo(obj); 首先class_type obj_local(obj) ,這樣就定義了局部變量obj_local供函數內部使用
ii)引用傳遞:
無論對內置類型還是類類型,傳遞引用或指針最終都是傳遞的地址值!而地址總是指針類型(屬于簡單類型), 顯然參數傳遞時,按簡單類型的賦值拷貝,而不會有拷貝構造函數的調用(對于類類型).
3是在類中有指針數據成員時,拷貝構造函數的使用?
如果不顯式聲明拷貝構造函數的時候,編譯器也會生成一個默認的拷貝構造函數,而且在一般的情況下運行的也很好。但是在遇到類有指針數據成員時就出現問題了:因為默認的拷貝構造函數是按成員拷貝構造,這導致了兩個不同的指針(如ptr1=ptr2)指向了相同的內存。當一個實例銷毀時,調用析構函數free(ptr1)釋放了這段內存,那么剩下的一個實例的指針ptr2就無效了,在被銷毀的時候free(ptr2)就會出現錯誤了, 這相當于重復釋放一塊內存兩次。這種情況必須顯式聲明并實現自己的拷貝構造函數,來為新的實例的指針分配新的內存。
問題1和2回答了為什么拷貝構造函數使用值傳遞會產生無限遞歸調用的問題;
問題3回答了回答了在類中有指針數據成員時,拷貝構造函數使用值傳遞等于白顯式定義了拷貝構造函數,因為默認的拷貝構造函數就是這么干的。
這樣我終于看明白了。作者寫得的確好。
posted @
2009-06-18 11:13 Sandy 閱讀(648) |
評論 (0) |
編輯 收藏
摘自:
http://www.shnenglu.com/yearner/archive/2008/11/09/66447.html對于智能指針,也只是聽說而已,對深層的東西也不甚了解。昨日又重聽這一字眼,想想多少也該了解一些。
淺談C++的智能指針
內存泄露是C++程序員都頭疼的大
問題。C++缺乏像JAVA、C#一樣,擁有GC這么一項有利的武器,它將內存管理的部分
權限交給了程序員。雖然GC的存在節約了開發、排錯的時間與成本,但是C++為了追求運行
速度而20年來堅決不予補充進其標準。(題外話:C++通過加大開發難度去換取執行速度的做法,在現在看來不知是否能給與正面的評價,還是留給將來再說吧。)
從此,在堆上申請了內存忘了釋放、所造成的內存泄露的問題就一直困擾著C++程序員。也許為了稍許彌補沒有垃圾回收器所造成的開發門檻高,各大廠商開發的C++庫中都像COM學習引入智能指針試圖解決部分目前存在的問題。
智能指針是存儲指向動態分配(堆)對象指針的類, 用于生存期控制, 能夠確保自動正確的銷毀動態分配的對象,防止內存泄露。它的一種通用實現技術是使用引用計數(reference count)。智能指針類將一個計數器與類指向的對象相關聯,引用計數跟蹤該類有多少個對象共享同一指針。每次創建類的新對象時,初始化指針并將引用計數置為1;當對象作為另一對象的副本而創建時,拷貝構造函數拷貝指針并增加與之相應的引用計數;對一個對象進行賦值時,賦值操作符減少左操作數所指對象的引用計數(如果引用計數為減至0,則刪除對象),并增加右操作數所指對象的引用計數;調用析構函數時,構造函數減少引用計數(如果引用計數減至0,則刪除基礎對象)。
說到智能指針,我們一定要看看標準C++庫提供的“搞笑的”智能指針:auto_ptr。
標準庫中提供了C++程序的基本設施。雖然C++標準庫隨著C++標準折騰了許多年,直到標準的出臺才正式定型,網上評論C++標準庫時都說:“在標準庫的實現上卻很令人欣慰得看到多種實現,并且已被實踐證明為有工業級別強度的佳作。”但目前的標準C++中,只有一種獨苗智能指針:std::auto_ptr。
auto_ptr指針是一個RAII對象,它初始化時獲得資源,析構時自動釋放資源(生命期結束).它的缺點數不勝數:
1、auto_ptr要求一個對象只能有一個擁有者,嚴禁一物二主
2、缺少對引用數和數組的支持。
3、不可將auto_ptr對象作為STL容器的元素。C++標準明確禁止這樣做,否則可能會碰到不可預見的結果。(這一條暈死一
大片)。
4、auto_ptr在被復制的時候會傳輸所有權
反正由此可見:標準庫的智能指針就是無甚大用。
在這樣的情況下,C++標準委員會自然需要考慮引入新的智能指針。目前由C++標準委員會庫工作組發起的Boost 組織開發了Boost系列智能指針。
在Boost中的智能指針有五種: scoped_ptr,scoped_array,shared_ptr,shared_array,weak_ptr.
前4種完全是針對標準庫中的auto_ptr提出解決方案,如:scope_ptr是針對“auto_ptr在被復制的時候會傳輸所有權”這一弱點提出的。最后一種沒見過,看名字像是弱引用智能指針,我懷疑
是不是類似于JAVA中弱引用一樣,有待進一步學習。
還查到一篇:
C++深度探索系列:智能指針(Smart Pointer) [一] http://dev.csdn.net/develop/article/17/17530.shtm 有空可以看看!
posted @
2009-06-18 10:47 Sandy 閱讀(377) |
評論 (0) |
編輯 收藏