FLTK stands for Fast Light Toolkit
一樣是C++ cross-platform(最近寫code都會想要同時能在各種平台上跑, 因為我覺得porting實在是浪費生命的行為), 聽說真的很簡單容易上手......改天來玩玩
2007年12月19日 星期三
2007年12月8日 星期六
一行HTML就讓你的IE當掉
一個日本人發現的, 只要網頁有下列一行HTML, 就會讓IE crash, 我測試過目前IE6的確會crash
資料來源 - http://immike.net/blog/2007/08/06/single-line-of-html-crashes-ie-6/
我的AntiVir防毒可以偵測到, 卡巴也可以偵測到, 看來這幾家防毒軟體反應還蠻快的, 倒是目前微軟還沒發佈修正檔呢
<style>*{position:relative}</style><table><input></table>測試網址 - http://immike.net/scripts/ie_crash.html
資料來源 - http://immike.net/blog/2007/08/06/single-line-of-html-crashes-ie-6/
我的AntiVir防毒可以偵測到, 卡巴也可以偵測到, 看來這幾家防毒軟體反應還蠻快的, 倒是目前微軟還沒發佈修正檔呢
2007年11月19日 星期一
Boost asio related - Pion Network Library
Pion Network Library
open source, Boost Software License, 主要實做HTTP(S)相關的功能
底層是用Boost和asio, 這表示asio已經可以用在production上囉
想要reliable and portable的networking library? 選asio準沒錯!!
open source, Boost Software License, 主要實做HTTP(S)相關的功能
底層是用Boost和asio, 這表示asio已經可以用在production上囉
想要reliable and portable的networking library? 選asio準沒錯!!
2007年11月15日 星期四
Blog文章加密
有時候想在blog上發一些牢騷, 可是又不想讓無關的人看到, 所以呢, 就想要自己寫個軟體來加解密之類的。但是!! 這個世界已經是開放自由的世界, 所以這種東西一定有人已經做過了, google一下馬上就發現啦 - JavaScrypt。
顧名思義, 這是利用Javascript來做加解密, 演算法是AES-256。Javascript雖然不快, 但是有一個非常大的好處, 就是可以在browser上面跑。所以啦, 我可以用Javascript跳出一個密碼視窗讓人家輸入密碼, 然後利用動態網頁技術直接將解密後的原文印出來, 這是不是比copy-paste到軟體裡面做加解密方便多了呢!?
不僅如此, 還有熱心的人連跳出密碼視窗這些javascript都幫我們寫好了, 請看Encryted blog posts。他寫好的javascript放在http://www.psi.toronto.edu/~vincent/blog/blogjscrypt.js, 想要在blog裡面用的人直接include進來就可以了, 有安全疑慮的人, 可以把js檔copy回去放在可信任的地方或是直接貼在HTML裡。另外, 他還提供了線上加解密的工具 - Javascript Encryption and Decryption, 可以讓我們輕鬆產生加密文。
有了這東西, 以後就可以盡情的講八卦了(咦?), 現在就來說個八卦, 密碼是我現任公司的協理的(暱稱)加(姓), 共7個小寫英文字母(很明顯 , 這個八卦只有少數人能夠知道......)
按這裡解密
顧名思義, 這是利用Javascript來做加解密, 演算法是AES-256。Javascript雖然不快, 但是有一個非常大的好處, 就是可以在browser上面跑。所以啦, 我可以用Javascript跳出一個密碼視窗讓人家輸入密碼, 然後利用動態網頁技術直接將解密後的原文印出來, 這是不是比copy-paste到軟體裡面做加解密方便多了呢!?
不僅如此, 還有熱心的人連跳出密碼視窗這些javascript都幫我們寫好了, 請看Encryted blog posts。他寫好的javascript放在http://www.psi.toronto.edu/~vincent/blog/blogjscrypt.js, 想要在blog裡面用的人直接include進來就可以了, 有安全疑慮的人, 可以把js檔copy回去放在可信任的地方或是直接貼在HTML裡。另外, 他還提供了線上加解密的工具 - Javascript Encryption and Decryption, 可以讓我們輕鬆產生加密文。
有了這東西, 以後就可以盡情的講八卦了(咦?), 現在就來說個八卦, 密碼是我現任公司的協理的(暱稱)加(姓), 共7個小寫英文字母(很明顯 , 這個八卦只有少數人能夠知道......)
VF6+OLxpi/E7shYyCSetOKgYcy+UTpMjUaXohalzznu/ThTJ
YyDcLk3PwWBTbF4qFGWrVhksiHxpEPgFeGurXhfByeg6cjm9
zvfYVPo6FajiRgCSM2/RDi4NBDn0B7BY1Ux9frQH2xg+um8o
tKsLtg==
YyDcLk3PwWBTbF4qFGWrVhksiHxpEPgFeGurXhfByeg6cjm9
zvfYVPo6FajiRgCSM2/RDi4NBDn0B7BY1Ux9frQH2xg+um8o
tKsLtg==
按這裡解密
2007年11月6日 星期二
汐止真不適合住人
嗯...已經連續下雨一個多禮拜了, 這場雨......還沒有停過
每個冬天都是這樣, 又冷又濕的
啊, 又讓我想起台南, 那裡是個美好的地方
有晴朗的天空, 我想念的朋友家人, 和數不清的美食
很可惜啊, 因為我的工作性質, 不知道什麼時候才能回去我的故鄉
爛天氣加上國防役的束縛, 心情總是high不起來
我開始期待一年多後的環島之旅了, 自由的味道在那時候一定格外甜美
每個冬天都是這樣, 又冷又濕的
啊, 又讓我想起台南, 那裡是個美好的地方
有晴朗的天空, 我想念的朋友家人, 和數不清的美食
很可惜啊, 因為我的工作性質, 不知道什麼時候才能回去我的故鄉
爛天氣加上國防役的束縛, 心情總是high不起來
我開始期待一年多後的環島之旅了, 自由的味道在那時候一定格外甜美
Boost asio 0.3.8 is released
其實已經release一兩個禮拜了
只是今天用SSL老是crash, 翻了翻mail list看到有人說0.3.8可以解決, 就順手來更新了...
asio 0.3.8為了符合TR2 networking proposal, 在error handling上做了不小的改變
例如0.3.7的boost::asio::error, 在0.3.8通通不見了, 取而代之的是boost::system::error_code
(Boost System也是為了TR2而生的, 寫過socket程式的人都知道, 在win32底下我們要用WSAGetLastError()來取得error code, 在linux下則是用errno, 不怎麼方便, Boost System解決了這個問題)
除了error code, 本來的error handler也不見了
0.3.7會pass像boost::asio::ignore_error()這樣的error handler去取error
0.3.8直接把boost::system::error_code用pass-by-reference傳進去, 看起來清楚多了, 不過我覺得比較不方便一點, 因為我喜歡ignore error......
P.S. 為什麼asio明明看起來就像是網路的library, 名字卻要取為asio呢?
這是因為作者的原始初衷是asynchronous IO的concept, 只是目前只有網路先被implement出來......
不過asio的asynchronous concept, 一開始雖然很不習慣, 但卻是很不賴的思考邏輯喔
只是今天用SSL老是crash, 翻了翻mail list看到有人說0.3.8可以解決, 就順手來更新了...
asio 0.3.8為了符合TR2 networking proposal, 在error handling上做了不小的改變
例如0.3.7的boost::asio::error, 在0.3.8通通不見了, 取而代之的是boost::system::error_code
(Boost System也是為了TR2而生的, 寫過socket程式的人都知道, 在win32底下我們要用WSAGetLastError()來取得error code, 在linux下則是用errno, 不怎麼方便, Boost System解決了這個問題)
除了error code, 本來的error handler也不見了
0.3.7會pass像boost::asio::ignore_error()這樣的error handler去取error
0.3.8直接把boost::system::error_code用pass-by-reference傳進去, 看起來清楚多了, 不過我覺得比較不方便一點, 因為我喜歡ignore error......
P.S. 為什麼asio明明看起來就像是網路的library, 名字卻要取為asio呢?
這是因為作者的原始初衷是asynchronous IO的concept, 只是目前只有網路先被implement出來......
不過asio的asynchronous concept, 一開始雖然很不習慣, 但卻是很不賴的思考邏輯喔
2007年10月22日 星期一
STL map的insert與Java Hashtable的put
當Java的Hashtable已經含有(K,V)這個pair, 而我們又put(K, Vn)的時候
Vn會取代掉V, 並且把V return回來, 但是在STL map的insert卻不是這樣......
STL map的insert並不會取代舊的, 只會傳回pair<iterator, bool>這樣的pair object
然後在boolean value那邊設為false, iterator則指向那個已經存在的value, 所以insert失敗後要接下去用iterator來取代舊的
寫Java的人轉到STL應該都會踩過這個陷阱吧, 如果不好好讀文件的話......
Vn會取代掉V, 並且把V return回來, 但是在STL map的insert卻不是這樣......
STL map的insert並不會取代舊的, 只會傳回pair<iterator, bool>這樣的pair object
然後在boolean value那邊設為false, iterator則指向那個已經存在的value, 所以insert失敗後要接下去用iterator來取代舊的
寫Java的人轉到STL應該都會踩過這個陷阱吧, 如果不好好讀文件的話......
2007年10月12日 星期五
2007年9月30日 星期日
一個多月沒寫blog了......
最近真的好累, 是精神上的累
現實和原則一直在我腦中衝撞, 我還太嫩, 不能百分百確定誰是對的
剩一年又三個月, 白痴才會回去當兵吧
只是好心情一直被搞砸, 看來我的EQ還需要磨練, 剩下的時間就來練到完全不動凡心的境界吧
整天往壞處想不只對現況沒有好處, 還會影響到身邊的人, 這是我所不願意的
我也常常禱告, 總會出自人類的私心, 但是,
阿爸!父啊!在你凡事都能;求你將這杯撤去。然而,不要從我的意思,只要從你的意思。
馬可福音 14:36
現實和原則一直在我腦中衝撞, 我還太嫩, 不能百分百確定誰是對的
剩一年又三個月, 白痴才會回去當兵吧
只是好心情一直被搞砸, 看來我的EQ還需要磨練, 剩下的時間就來練到完全不動凡心的境界吧
整天往壞處想不只對現況沒有好處, 還會影響到身邊的人, 這是我所不願意的
我也常常禱告, 總會出自人類的私心, 但是,
阿爸!父啊!在你凡事都能;求你將這杯撤去。然而,不要從我的意思,只要從你的意思。
馬可福音 14:36
2007年8月24日 星期五
MMovie
MMovie = MMO + Movie, 多人網路線上遊戲的動畫作成電影, 這次VOIG公司要推出以WOW的遊戲為主題的電影耶。以WOW的遊戲畫面來做電影的手法還蠻常見的, 我最印象深刻的就是那一部號稱史詩的電影和南方四劍客......(Mom!! Bathroom!! Bathroom!!)
這次VOIG推出兩分多鐘的預告片, 而且不久以後將推出正式的電影......要進電影院看的=.=。我很好奇會有幾個人去看啦......不過全世界WOW的玩家這麼多, 票房說不定還不錯哩, 不過我是不會花錢跑去看的啦, 哈哈哈, 我只要玩就好了, 電影嘛......總是有機會可以看到的嘛......
以下為預告片內容
KUSO點詳解, 轉載自PTT WOW版
0:02-鬥陣俱樂部
0:21-畢業生
0:30-星際大戰
0:36-古墓奇兵
0:41-拿破崙炸藥
0:48-公主新娘
0:52-魔戒
0:58-鐵達尼號
1:06-魔鬼終結者(原文最後是要摩托車)
1:20-三百壯士
1:29-法櫃奇兵
1:36-當哈利遇見了莎莉
1:58-綠野仙蹤
2:03-ID4(但是ID4有兩個人,而且是男的,相當不確定)
這次VOIG推出兩分多鐘的預告片, 而且不久以後將推出正式的電影......要進電影院看的=.=。我很好奇會有幾個人去看啦......不過全世界WOW的玩家這麼多, 票房說不定還不錯哩, 不過我是不會花錢跑去看的啦, 哈哈哈, 我只要玩就好了, 電影嘛......總是有機會可以看到的嘛......
以下為預告片內容
KUSO點詳解, 轉載自PTT WOW版
0:02-鬥陣俱樂部
0:21-畢業生
0:30-星際大戰
0:36-古墓奇兵
0:41-拿破崙炸藥
0:48-公主新娘
0:52-魔戒
0:58-鐵達尼號
1:06-魔鬼終結者(原文最後是要摩托車)
1:20-三百壯士
1:29-法櫃奇兵
1:36-當哈利遇見了莎莉
1:58-綠野仙蹤
2:03-ID4(但是ID4有兩個人,而且是男的,相當不確定)
2007年8月10日 星期五
2007年8月9日 星期四
Boost lexical_cast
http://www.boost.org/libs/conversion/lexical_cast.htm
屬於Boost Conversion Library下的一支,很平常的功能,卻有莫大的幫助。
我想很多C++ programmer遇到要把一個字串轉成整數的情況時,還是會不由自主的使用C時代的atoi。但是atoi有一個很嚴重的問題,就是轉換失敗時一律回傳0,這樣就不知道到底真的是0還是轉換失敗了。
C++的IOstream本身就提供了很好用的類別 - stringstream。
stringstream s("12345");
int d;
s >> d;
可以呼叫fail()來測試轉換是否成功,比atoi好了一點,但是卻比較囉唆,為了轉換一個字串還要在stack裡多產生一個stringstream的object,讓人有點擔心效率。於是,Boost lexical_cast就誕生了:
int d = boost::lexical_cast<int>("12345");
很簡潔的寫法,轉換錯誤的話會丟出bad_lexical_cast這個exception。
那整數要轉成string呢?古早時代有人會用itoa這種非標準的函式來做,現在大部分的programmer可能都懂得要用sprintf這個比較general的function來做:
char s[32];
int d = 12345;
sprintf(s, "%d", d);
而lexical_cast的作法還是一樣:
int d = 12345;
string s = boost::lexical_cast<string>(d);
所以,把atoi丟掉吧,C++時代不用再遷就C的老舊函式了。
屬於Boost Conversion Library下的一支,很平常的功能,卻有莫大的幫助。
我想很多C++ programmer遇到要把一個字串轉成整數的情況時,還是會不由自主的使用C時代的atoi。但是atoi有一個很嚴重的問題,就是轉換失敗時一律回傳0,這樣就不知道到底真的是0還是轉換失敗了。
C++的IOstream本身就提供了很好用的類別 - stringstream。
stringstream s("12345");
int d;
s >> d;
可以呼叫fail()來測試轉換是否成功,比atoi好了一點,但是卻比較囉唆,為了轉換一個字串還要在stack裡多產生一個stringstream的object,讓人有點擔心效率。於是,Boost lexical_cast就誕生了:
int d = boost::lexical_cast<int>("12345");
很簡潔的寫法,轉換錯誤的話會丟出bad_lexical_cast這個exception。
那整數要轉成string呢?古早時代有人會用itoa這種非標準的函式來做,現在大部分的programmer可能都懂得要用sprintf這個比較general的function來做:
char s[32];
int d = 12345;
sprintf(s, "%d", d);
而lexical_cast的作法還是一樣:
int d = 12345;
string s = boost::lexical_cast<string>(d);
所以,把atoi丟掉吧,C++時代不用再遷就C的老舊函式了。
2007年8月1日 星期三
Distributed Web Crawler - Grub
http://www.grub.org/
這東西很妙...類似SETI@home那樣,電腦閒閒沒事做的人可以下載Grub的client回家裝,這樣就可以幫忙去"爬"網路上的網頁,然後做一些index的處理,再送回Grub的資料庫存起來。理論上這是集眾人之力來索引整個Internet的終極方法。
今天有一個新聞,Wikia的創辦人Jimmy Wales買下了Grub,打算用來挑戰Google或Yahoo這些強大的search engine,靠的就是Grub背後這個資料庫。
不過,這樣不就變成大家幫他們找資料,錢都是他們賺嗎?我自己也寫過web crawler,最棘手的問題就是頻寬不夠或是機器不夠......,Grub這一招讓這些難題都迎刃而解。當然也有很多人質疑說為什麼他們可以拿大家爬來的資料來賺錢,Grub是說open source不等於免費啦,還有可以優先爬自己的網站增加自己網站的曝光率等等,當然他們也有提供interface可以讓任何人使用這個資料庫啦......不過資料庫還是在他們那裡就是了。
Grub這樣的賺錢手法我個人認為還好,有名大站不也是靠大家貼照片和寫blog來賺錢嗎?Web 2.0時代嘛......內容提供者由以前的網站變成使用者自己,想賺錢的就看誰能夠吸引最多人來提供內容囉。對我來說,我對那個可以索引網頁的interface比較感興趣......
這東西很妙...類似SETI@home那樣,電腦閒閒沒事做的人可以下載Grub的client回家裝,這樣就可以幫忙去"爬"網路上的網頁,然後做一些index的處理,再送回Grub的資料庫存起來。理論上這是集眾人之力來索引整個Internet的終極方法。
今天有一個新聞,Wikia的創辦人Jimmy Wales買下了Grub,打算用來挑戰Google或Yahoo這些強大的search engine,靠的就是Grub背後這個資料庫。
不過,這樣不就變成大家幫他們找資料,錢都是他們賺嗎?我自己也寫過web crawler,最棘手的問題就是頻寬不夠或是機器不夠......,Grub這一招讓這些難題都迎刃而解。當然也有很多人質疑說為什麼他們可以拿大家爬來的資料來賺錢,Grub是說open source不等於免費啦,還有可以優先爬自己的網站增加自己網站的曝光率等等,當然他們也有提供interface可以讓任何人使用這個資料庫啦......不過資料庫還是在他們那裡就是了。
Grub這樣的賺錢手法我個人認為還好,有名大站不也是靠大家貼照片和寫blog來賺錢嗎?Web 2.0時代嘛......內容提供者由以前的網站變成使用者自己,想賺錢的就看誰能夠吸引最多人來提供內容囉。對我來說,我對那個可以索引網頁的interface比較感興趣......
2007年7月25日 星期三
Boost 1.34.1 Released
http://www.boost.org/index.htm
It is a recommended upgrade for all users of Boost 1.34.0
那些新的lib還沒被納入,例如asio等。據mail-list上的可靠消息指出,要等到1.35.0才會加進來......
It is a recommended upgrade for all users of Boost 1.34.0
那些新的lib還沒被納入,例如asio等。據mail-list上的可靠消息指出,要等到1.35.0才會加進來......
2007年7月24日 星期二
How to interpret complex C/C++ declarations
http://www.codeproject.com/cpp/complex_declarations.asp
C時代的指標已經夠複雜了, C++時代又加入了const和reference這兩個東西, 事情愈來愈複雜了。
int const * n;
像const被塞在中間, 我想初學者一定會很不確定說這個const到底是修飾int, 還是指標? 上面那篇文章提了一個"讀懂宣告"的秘訣......就是由右往左讀。所以, n是一個指標指向一個const int。
int *&p;
那這個呢? 一樣由右往左讀, p是一個reference參考到一個int指標。
const char * const * const s;
這個例子就比較極端了......正常情況下應該要避免這種複雜的宣告。但是, 還是給他解讀一下, s是一個const pointer to const pointer to const char。這個宣告等於下面這個宣告:
char const * const * const s;
const char變成char const而已, 不過這樣的宣告方式就讓由右向左的讀法比較通順了, 所以, 宣告的時候要盡量寫成這種讀起來比較通順的style。
C時代的指標已經夠複雜了, C++時代又加入了const和reference這兩個東西, 事情愈來愈複雜了。
int const * n;
像const被塞在中間, 我想初學者一定會很不確定說這個const到底是修飾int, 還是指標? 上面那篇文章提了一個"讀懂宣告"的秘訣......就是由右往左讀。所以, n是一個指標指向一個const int。
int *&p;
那這個呢? 一樣由右往左讀, p是一個reference參考到一個int指標。
const char * const * const s;
這個例子就比較極端了......正常情況下應該要避免這種複雜的宣告。但是, 還是給他解讀一下, s是一個const pointer to const pointer to const char。這個宣告等於下面這個宣告:
char const * const * const s;
const char變成char const而已, 不過這樣的宣告方式就讓由右向左的讀法比較通順了, 所以, 宣告的時候要盡量寫成這種讀起來比較通順的style。
2007年7月11日 星期三
2007年7月9日 星期一
Boost Pointer Container
http://www.boost.org/libs/ptr_container/doc/ptr_container.html
顧名思義就是存放pointer的container,exception-safe。以前我們會用這樣的方法來存放pointer:
std::vector<MyClass*> myvector;
myvector.push_back(new MyClass());
myvector[0]->do_something();
上面這段code還沒寫完喔,因為我們存的是pointer,所以之後還要去注意釋放那些pointer所allocate的memory。
現在Boost Pointer Container裡面有個ptr_vector可以對應std::vector
boost::ptr_vector<MyClass> myvector;
myvector.push_back(new MyClass());
myvector[0].do_something();
code有點不一樣,可以看到的是,我們無法從Pointer Container取回pointer了,這可以避免一些意外情況發生。另外,所有的Pointer Container都會在解構時自動釋放pointer所佔的記憶體。
看到這邊有人可能會想:不過是自動釋放記憶體嘛......我自己寫code都很細心,都會注意memory的釋放,這個pointer container沒多大用處嘛。不過,Pointer Container最重要的重點是exception-safe,何謂exception-safe?參考下面這一段code:
在exception發生時,還沒到釋放memory的地方就跳出function了,這裡就會造成memory leak。雖然我們可以在catch裡都加上處理記憶體問題的code,但這樣的作法可能會非常的tedious(沒有人會想在每個catch裡都寫一次release memory的code吧?)。所以,有人會用std::auto_ptr或boost::shared_ptr這種smart pointer來解決這種問題:
std::vector<boost::shared_ptr<MyClass> > myvector;
C++ exception handling保證跳出function以前,所有的stack object都會被正常清除。所以上述的smart pointer都能夠保證在exception發生時,自動釋放pointer所指的memory。不過,使用smart pointer會多出一些overhead,而Pointer Container內部的實做則是直接將指標轉換成void*來儲存,顯然比smart pointer的效率要高。
基本上每個STL container在Boost Pointer Container都有互相對應的類別可以使用,例如vector對應ptr_vector,map對應ptr_map,操作方法也一樣,還擴充了一些便利的方法,例如我們可以直接用ptr_map.insert(k, v),不必像以前的std::map還要先create出一個pair object。
顧名思義就是存放pointer的container,exception-safe。以前我們會用這樣的方法來存放pointer:
std::vector<MyClass*> myvector;
myvector.push_back(new MyClass());
myvector[0]->do_something();
上面這段code還沒寫完喔,因為我們存的是pointer,所以之後還要去注意釋放那些pointer所allocate的memory。
現在Boost Pointer Container裡面有個ptr_vector可以對應std::vector
boost::ptr_vector<MyClass> myvector;
myvector.push_back(new MyClass());
myvector[0].do_something();
code有點不一樣,可以看到的是,我們無法從Pointer Container取回pointer了,這可以避免一些意外情況發生。另外,所有的Pointer Container都會在解構時自動釋放pointer所佔的記憶體。
看到這邊有人可能會想:不過是自動釋放記憶體嘛......我自己寫code都很細心,都會注意memory的釋放,這個pointer container沒多大用處嘛。不過,Pointer Container最重要的重點是exception-safe,何謂exception-safe?參考下面這一段code:
void func()
{
std::vector<MyClass*> myvector;
myvector.push_back(new MyClass());
try
{
// Exceptions may occur here
}
catch(...)
{
throw;
}
// I'm a good programmer
delete myvector[0];
}
在exception發生時,還沒到釋放memory的地方就跳出function了,這裡就會造成memory leak。雖然我們可以在catch裡都加上處理記憶體問題的code,但這樣的作法可能會非常的tedious(沒有人會想在每個catch裡都寫一次release memory的code吧?)。所以,有人會用std::auto_ptr或boost::shared_ptr這種smart pointer來解決這種問題:
std::vector<boost::shared_ptr<MyClass> > myvector;
C++ exception handling保證跳出function以前,所有的stack object都會被正常清除。所以上述的smart pointer都能夠保證在exception發生時,自動釋放pointer所指的memory。不過,使用smart pointer會多出一些overhead,而Pointer Container內部的實做則是直接將指標轉換成void*來儲存,顯然比smart pointer的效率要高。
基本上每個STL container在Boost Pointer Container都有互相對應的類別可以使用,例如vector對應ptr_vector,map對應ptr_map,操作方法也一樣,還擴充了一些便利的方法,例如我們可以直接用ptr_map.insert(k, v),不必像以前的std::map還要先create出一個pair object。
2007年7月4日 星期三
ClickClickClick的後續......
Click*3續觀察 : 圖形驗證與網路分工
Mr./Ms. Days上的一篇文章,詳細的解說了各個兵器的技術細節。
原本以為只是一個無聊遊戲,就像以前有一個自動練功的online game,只要掛著縮小到系統列就會自動升級,非常的空虛......那時候剛開始也是很流行,不過沒多久鄉民們就玩膩了。這次的click*3巧妙的把競爭層級拉到國與國之間的戰爭,因此在民族情感的發酵作用下,各國鄉民(宅宅?)們前仆後繼,就算是如此空虛的滑鼠點擊比賽也一直樂此不疲。
值得一提的是,網站主人並沒有刻意限制web robot(或許這才是他的目的?),於是讓各方人馬相繼開發出各種不錯的自動化兵器,看起來還蠻有趣的耶。真希望我還是學生,那我就有時間可以來玩玩這個了......
Mr./Ms. Days上的一篇文章,詳細的解說了各個兵器的技術細節。
原本以為只是一個無聊遊戲,就像以前有一個自動練功的online game,只要掛著縮小到系統列就會自動升級,非常的空虛......那時候剛開始也是很流行,不過沒多久鄉民們就玩膩了。這次的click*3巧妙的把競爭層級拉到國與國之間的戰爭,因此在民族情感的發酵作用下,各國鄉民(宅宅?)們前仆後繼,就算是如此空虛的滑鼠點擊比賽也一直樂此不疲。
值得一提的是,網站主人並沒有刻意限制web robot(或許這才是他的目的?),於是讓各方人馬相繼開發出各種不錯的自動化兵器,看起來還蠻有趣的耶。真希望我還是學生,那我就有時間可以來玩玩這個了......
2007年7月2日 星期一
青山瀑布
2007年6月29日 星期五
軟體才是登峰造極的關鍵
最近iPhone很出名,媒體幾乎都不約而同的讚美=.=...但是也有人提出反駁,指明iPhone的一些功能明明不怎麼樣,例如相機畫素不足或是不支援GPS之類的,相較之下台灣宏達電的手機在功能上反而更剩iPhone一籌呢。
但iPhone之所以會那麼受眾人喜愛,卻不是沒有原因的。看過iPhone的實機demo,真的會不禁讚嘆:這種質感,這種流暢度,真的只是一隻手機嗎XD。畫面精美就不用說了,用手指可以控制整個網頁,翻轉90度字會跟著轉,usability實在是達到出神入化的境界了。台灣代工業很強沒錯,但是軟體才是登峰造極的關鍵啊。硬體功能愈來愈強,到了某一個程度以後,能夠脫穎而出得到消費者青睞的,就只有搭配超強軟體的硬體了。
軟體業所擁有的先天優勢應該不用多說了,但這是一條漫長辛苦的路,很少公司願意等那麼久的時間。台灣現在的軟體業大部分只能靠政府案子過活,做的是軟體代工業(代工業比較快獲利,似乎很受台灣老闆喜愛),但是做事方法又不如印度的專業,整個就是毫無前景可言。政府似乎無法提出有效的解決方案,只是不停的發案試著要餵飽這些"軟體公司",但是古有名言,給他魚吃不如教他捕魚,這句話還蠻有道理的=.=。軟體業找不到人才也是原因之一,因為人才都跑去會賺大錢的行業去了,我覺得台灣可以仿照韓國政府的作法,進來遊戲軟體業不用當兵這樣,因為台灣年輕人真的很不喜歡當兵,這樣一定可以找到很多人才的,難怪韓國OLG這麼囂張=.=
但iPhone之所以會那麼受眾人喜愛,卻不是沒有原因的。看過iPhone的實機demo,真的會不禁讚嘆:這種質感,這種流暢度,真的只是一隻手機嗎XD。畫面精美就不用說了,用手指可以控制整個網頁,翻轉90度字會跟著轉,usability實在是達到出神入化的境界了。台灣代工業很強沒錯,但是軟體才是登峰造極的關鍵啊。硬體功能愈來愈強,到了某一個程度以後,能夠脫穎而出得到消費者青睞的,就只有搭配超強軟體的硬體了。
軟體業所擁有的先天優勢應該不用多說了,但這是一條漫長辛苦的路,很少公司願意等那麼久的時間。台灣現在的軟體業大部分只能靠政府案子過活,做的是軟體代工業(代工業比較快獲利,似乎很受台灣老闆喜愛),但是做事方法又不如印度的專業,整個就是毫無前景可言。政府似乎無法提出有效的解決方案,只是不停的發案試著要餵飽這些"軟體公司",但是古有名言,給他魚吃不如教他捕魚,這句話還蠻有道理的=.=。軟體業找不到人才也是原因之一,因為人才都跑去會賺大錢的行業去了,我覺得台灣可以仿照韓國政府的作法,進來遊戲軟體業不用當兵這樣,因為台灣年輕人真的很不喜歡當兵,這樣一定可以找到很多人才的,難怪韓國OLG這麼囂張=.=
2007年6月25日 星期一
Boost Thread
http://www.boost.org/doc/html/thread.html
Boost也提供了跨平台的多執行緒函式庫,該有的都有(R/W mutex還有問題,還沒正式納入),不過跟普通的多執行緒函式庫有點不同
1. 啟動方法
使用pthread的programmer會用以下方法啟動一個 thread
pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg);
start_routine就是thread的進入點,arg是要傳入的參數,因為只能傳一個參數,所以我們通常都是把所有參數擠在一個struct裡面......
Boost Thread是在建立thread物件時啟動一個執行緒的
boost::thread *mythread = new boost::thread(&threadfunc);
跟 一般不同的是,Boost Thread是接受Boost Function來當作thread的進入點,而不是一般的function pointer而已,上面範例的function pointer只是Boost Function的其中一種type而已, 所以, 我們可以輕鬆做到以下這種事:
直 接把non-static member function當成thread的進入點!!在以前pthread的時代,想要跑non-static member function非常麻煩,通常要寫個static wrapper之類的......拜Boost Function和Boost Bind之賜,這兩者與Boost Thread的完美結合,讓C++ programmer的生活更輕鬆了!!
有人可能已經發現了,Boost Thread在創造thread的時候,沒有地方可以傳參數進去阿!!Well,有了Boost Bind,這根本就不是問題,還能做的比以前更好。
不像以前只能傳void*參數,使用bind想要傳幾個都可以,而且還是type-safe的方式。不過,既然都可以bind member function了,把參數當作member variable的寫法可能比較好
2. Mutex的概念
以前在pthread我們都會這樣來使用mutex
Boost Thread則是把lock當成一個物件,建構出來時表示鎖住一個mutex,解構表示解鎖一個mutex。
由 於lock是stack-allocated的物件,所以在function結束後,lock會自動被摧毀,mutex就會處於unlocked狀態。 Boost Thread的lock都不保證thread-safe,其實它最好應該都被使用在stack裡,thread之間只要share mutex就可以了。
把critical section用括號包起來,然後在最前面創造一個lock,這樣就可以保證這個block的thread-safe了,這樣的寫法比較直覺而且簡潔多了,不會再像以前一樣忘記unlock mutex......
Boost Thread也有一些不足,例如沒有r/w mutex和thread termination。在很多thread lib裡,thread termination通常會牽涉到thread-safe的問題,所以大多數都會有個warning提醒programmer最好不要使用thread termination以避免發生問題(例如memory leak)。事實上,thread termination最好自己在thread裡面implement,才是最保險的作法。
Boost也提供了跨平台的多執行緒函式庫,該有的都有(R/W mutex還有問題,還沒正式納入),不過跟普通的多執行緒函式庫有點不同
1. 啟動方法
使用pthread的programmer會用以下方法啟動一個 thread
pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg);
start_routine就是thread的進入點,arg是要傳入的參數,因為只能傳一個參數,所以我們通常都是把所有參數擠在一個struct裡面......
Boost Thread是在建立thread物件時啟動一個執行緒的
boost::thread *mythread = new boost::thread(&threadfunc);
跟 一般不同的是,Boost Thread是接受Boost Function來當作thread的進入點,而不是一般的function pointer而已,上面範例的function pointer只是Boost Function的其中一種type而已, 所以, 我們可以輕鬆做到以下這種事:
struct MyClass
{
void threadfunc() {// do something}
};
int main()
{
MyClass m;
boost::thread mythread(boost::bind(&MyClass::threadfunc, &m));
// Wait for the thread...
}
直 接把non-static member function當成thread的進入點!!在以前pthread的時代,想要跑non-static member function非常麻煩,通常要寫個static wrapper之類的......拜Boost Function和Boost Bind之賜,這兩者與Boost Thread的完美結合,讓C++ programmer的生活更輕鬆了!!
有人可能已經發現了,Boost Thread在創造thread的時候,沒有地方可以傳參數進去阿!!Well,有了Boost Bind,這根本就不是問題,還能做的比以前更好。
struct MyClass
{
void threadfunc(int a, double b) {}
};
int main()
{
MyClass m;
boost::thread mythread(
boost::bind(&MyClass::threadfunc, &m, 1, 2.2));
// Wait for the thread
}
不像以前只能傳void*參數,使用bind想要傳幾個都可以,而且還是type-safe的方式。不過,既然都可以bind member function了,把參數當作member variable的寫法可能比較好
struct MyClass
{
void threadfunc() {}
int m_a;
double m_b;
};
int main()
{
MyClass m;
m.m_a = 1;
m.m_b = 2.2;
boost::thread mythread(boost::bind(&MyClass::threadfunc, &m));
// Wait for the thread
}
2. Mutex的概念
以前在pthread我們都會這樣來使用mutex
// declare mutex
pthread_mutex_t m;
pthread_mutex_init(&m, NULL);
void threadfunc(void* param)
pthread_mutex_lock(&m);
// Only one can enter here...
pthread_mutex_unlock(&m);
}
Boost Thread則是把lock當成一個物件,建構出來時表示鎖住一個mutex,解構表示解鎖一個mutex。
// declare mutex
boost::mutex m;
void threadfunc()
boost::mutex::scoped_lock lock(m);
// On exiting this function, the mutex is unlocked
}
由 於lock是stack-allocated的物件,所以在function結束後,lock會自動被摧毀,mutex就會處於unlocked狀態。 Boost Thread的lock都不保證thread-safe,其實它最好應該都被使用在stack裡,thread之間只要share mutex就可以了。
int threadfunc()
{
{
// The first critical section
boost::mutex::scoped_lock lock(m);
// do something
}
{
// The second critical section
boost::mutex::scoped_lock lock(m);
//do something
}
}
把critical section用括號包起來,然後在最前面創造一個lock,這樣就可以保證這個block的thread-safe了,這樣的寫法比較直覺而且簡潔多了,不會再像以前一樣忘記unlock mutex......
Boost Thread也有一些不足,例如沒有r/w mutex和thread termination。在很多thread lib裡,thread termination通常會牽涉到thread-safe的問題,所以大多數都會有個warning提醒programmer最好不要使用thread termination以避免發生問題(例如memory leak)。事實上,thread termination最好自己在thread裡面implement,才是最保險的作法。
2007年6月14日 星期四
Boost program_options
http://www.boost.org/doc/html/program_options.html
Parse command line裡的parameters從來都不是一件簡單的事, 雖然僅僅是字串的解析, 但是沒有一個programmer還想分心去煩惱這些無關緊要的小事, 就像C++的std::string一樣, 簡單有用的設計讓programmer的生活可以輕鬆一點。
使用Java的人應該都對CLI不陌生, 它隸屬於Apache Jakarta Project下的jakarta commons。基本上Boost Program_options做的事情就跟CLI一樣, 所以使用C++的人同樣有方便好用的library可以利用。Java好像比較容易在網路上找到資源, 不管是文件或是程式庫, 都比C++多樣化, 但是Boost出現後慢慢改善了C++的這種情況, 也的確讓很多C++ developer可以更輕鬆的寫程式......離題了
Example:
options_description有overload << 這個operator可以output到std::ostream, 也就是說, 我們可以用cout就能印出那一長串的usage information, 格式排版完全不用擔心, 非常方便。
加入選項, 第一個parameter是參數名稱, 用逗號來區分長選項和短選項, 像第一個就是可以接收--help或-h這種選項。當然也可以在選項裡設定要接受使用者輸入參數, 例如上面的--threads或-t可以讓使用者指定thread的個數。
再來就是parse command line的字串啦, argc跟argv就是那些熟悉的東西, 全部丟進去就好了, 3行code就搞定!!
基本用法大概就是這樣, 真的非常簡單, 以後寫command line程式不用再經歷parsing parameter的痛苦了......
Parse command line裡的parameters從來都不是一件簡單的事, 雖然僅僅是字串的解析, 但是沒有一個programmer還想分心去煩惱這些無關緊要的小事, 就像C++的std::string一樣, 簡單有用的設計讓programmer的生活可以輕鬆一點。
使用Java的人應該都對CLI不陌生, 它隸屬於Apache Jakarta Project下的jakarta commons。基本上Boost Program_options做的事情就跟CLI一樣, 所以使用C++的人同樣有方便好用的library可以利用。Java好像比較容易在網路上找到資源, 不管是文件或是程式庫, 都比C++多樣化, 但是Boost出現後慢慢改善了C++的這種情況, 也的確讓很多C++ developer可以更輕鬆的寫程式......離題了
Example:
namespace po = boost::program_options;
po::options_description desc("Available options");
options_description有overload << 這個operator可以output到std::ostream, 也就是說, 我們可以用cout就能印出那一長串的usage information, 格式排版完全不用擔心, 非常方便。
desc.add_options()
("help,h", "help message")
("server,s", "run as server")
("client,c", po::value<string>(),"run as client and connect to the specified IP")
("bind,b", po::value<string>(), "bind a source IP to the client")
("threads,t", po::value<int>(), "the number of concurrent connections")
;
加入選項, 第一個parameter是參數名稱, 用逗號來區分長選項和短選項, 像第一個就是可以接收--help或-h這種選項。當然也可以在選項裡設定要接受使用者輸入參數, 例如上面的--threads或-t可以讓使用者指定thread的個數。
po::variables_map vm;
po::store(po::parse_command_line(argc, argv, desc), vm);
po::notify(vm);
再來就是parse command line的字串啦, argc跟argv就是那些熟悉的東西, 全部丟進去就好了, 3行code就搞定!!
if (vm.count("help"))
{
cout << desc << endl;
return 1;
}
variables_map的count方法可以得知有哪些選項出現, 如果使用者想要看help, 那就用cout直接把options_description印出來就好了。if(vm.count("client"))直接取得剛剛已經宣告好型態的參數, 連atoi或是sprintf這些煩人的雜事都省了......
{
string sip = vm["client"].as<string>();
// connect to server...
}
基本用法大概就是這樣, 真的非常簡單, 以後寫command line程式不用再經歷parsing parameter的痛苦了......
點滑鼠大賽......
http://www.clickclickclick.com/
怎麼會有人這麼北七呢, 這種比賽到底有什麼意義啊XD
我想唯一的意義可能是, 可以看出哪一個國家的人最閒......或是哪一個國家的人用的滑鼠最耐操。台灣現在遠遠落後啊, 愛台灣的台灣人趕快衝啊!!
初步看了一下, 開始比賽前要先輸入圖形文字, 圖形文字是彩色而且是扭曲的, 這樣比較難作弊了。按了大約20下以後, 就會出現加入國家click總和的link, 按下去就可以幫台灣加分數。很奇怪的是, 要加入總和前並不用通過圖形文字的檢查, 這裡的防弊措施僅僅是一個隨機(我猜)的連結而已, 對於精通web robot的人而言, 這應該不是什麼問題才對。因此, 可能可以做出一個robot, 一開始只要輸入圖形文字, 然後就自動按個幾千下加分, 然後再循環, 繼續輸入圖形文字這樣。不過我們不是韓國人, 不可以作弊喔, 科科。
怎麼會有人這麼北七呢, 這種比賽到底有什麼意義啊XD
我想唯一的意義可能是, 可以看出哪一個國家的人最閒......或是哪一個國家的人用的滑鼠最耐操。台灣現在遠遠落後啊, 愛台灣的台灣人趕快衝啊!!
初步看了一下, 開始比賽前要先輸入圖形文字, 圖形文字是彩色而且是扭曲的, 這樣比較難作弊了。按了大約20下以後, 就會出現加入國家click總和的link, 按下去就可以幫台灣加分數。很奇怪的是, 要加入總和前並不用通過圖形文字的檢查, 這裡的防弊措施僅僅是一個隨機(我猜)的連結而已, 對於精通web robot的人而言, 這應該不是什麼問題才對。因此, 可能可以做出一個robot, 一開始只要輸入圖形文字, 然後就自動按個幾千下加分, 然後再循環, 繼續輸入圖形文字這樣。不過我們不是韓國人, 不可以作弊喔, 科科。
2007年6月12日 星期二
Unicode到底是什麼?
The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)
上面是一篇Joel的文章, 用淺顯易懂的文字說明Unicode的原理。不知道UTF-7, UTF-8, UTF-16, UTF-32嗎?看一下這篇文章吧......還有, wchar_t這個type在UNIX/LINUX上的GCC是4個byte, 在Windows是佔2個byte, programmer一定要注意到這個。
一般來說, unicode的implementation依平台不同, 甚至依compiler而不同, 如果想要避免這種implementation的差異, 可以用現在最portable的unicode支援 - ICU。ICU支援C/C++和Java, .NET好像沒有, 不過.NET有一個System.Text.Encoding, 這個也能支援unicode不同格式之間的互轉。
2007年6月11日 星期一
最近的超級星光大道......
最近楊蹤萎還真紅耶, 把"背叛"唱的比曹格還紅, 曹格不知作何感想......俺是不看這種節目的(碼的唱一首歌就要哭一次, 我會看到想揍人......), 但是在"耳濡目染"之下, 我對那個節目還蠻了解的......囧rz。其實背叛也不錯聽啦, 楊蹤萎唱得也很好, 我也列入我的KTV重點練習曲之一, 科科, 我還想給它改一下歌詞, 唱出來可以更符合我心裡的感慨︰
雨,不停落下來~
bug,怎麼還是在~
儘管我細心design,你要亂掰就亂掰,我一個人,欣賞悲哀~
code,只剩下無奈~
我,一直不願再去改~
程式裡指標之間,永遠都有bug能踩~
只要一改,跑不起來~~
#
緊緊相依的code如何拆分開,你比我清楚還要我說明白~
bug太多會讓人瘋狂的勇敢,我用背叛自己,完成你的喇賽~~~
把code亂改不問一句該不該,當作每週一次對你的交差
破破爛爛慘慘,今後都不管~~
*
只要你能愉快~~~
心,有一句感慨~
我,還能夠跟誰對白~~
在你要豪洨之前,請你再回頭看看~
那些虎爛,還在不在~~~
Repeat #, *
(間奏)
Repeat #, *, *
雨,不停落下來~
bug,怎麼還是在~
儘管我細心design,你要亂掰就亂掰,我一個人,欣賞悲哀~
code,只剩下無奈~
我,一直不願再去改~
程式裡指標之間,永遠都有bug能踩~
只要一改,跑不起來~~
#
緊緊相依的code如何拆分開,你比我清楚還要我說明白~
bug太多會讓人瘋狂的勇敢,我用背叛自己,完成你的喇賽~~~
把code亂改不問一句該不該,當作每週一次對你的交差
破破爛爛慘慘,今後都不管~~
*
只要你能愉快~~~
心,有一句感慨~
我,還能夠跟誰對白~~
在你要豪洨之前,請你再回頭看看~
那些虎爛,還在不在~~~
Repeat #, *
(間奏)
Repeat #, *, *
2007年6月8日 星期五
Visual C++ compile error C2011
因為用到ntohs, ntohl這些function, 所以有include到<winsock2.h>, compile時卻一直出現
'fdset' : 'struct' 型別重複定義
'hostent' : 'struct' 型別重複定義
......
很多類似這種重複定義的問題。有經驗的windows programmer應該會想到, 可能哪邊搞錯同時把<winsock.h>和<winsock2.h> include進來了, 可是search了一下project, 根本就沒有include到什麼<winsock.h>啊, 而且<winsock2.h>的開頭寫著:
#ifndef _WINSOCK2API_
#define _WINSOCK2API_
#define _WINSOCKAPI_ /* Prevent inclusion of winsock.h in windows.h */
有以上的#define, 應該就不會再去include到<winsock.h>裡面的東西了吧!? 應該是這樣沒錯, 除非......你寫成這樣:
#include <winsock.h>
#include <winsock2.h>
<winsock.h>可沒有什麼預防措施以避免include到<winsock2.h>, 所以這樣的排列就會造成<winsock2.h>裡面的定義全部跟<winsock.h>裡面的衝突。但是, 前面說過了, 我沒有include <winsock.h>啊!! 謎底揭曉了, VC的<windows.h>居然include <winsock.h>......, 而且如果include關係像以下這樣, 那一時之間也很難知道發生什麼問題......
myinc.h的內容
#include <windows.h>
...
main.cpp的內容
#include "myinc.h"
#include <winsock2.h>
main.cpp並沒有include <windows.h>, 是它的include file去include到的, 如果include file很多, 找起來會想撞牆......因此, 最好的方法還是以後都把<winsock2.h>擺最上面好了。
'fdset' : 'struct' 型別重複定義
'hostent' : 'struct' 型別重複定義
......
很多類似這種重複定義的問題。有經驗的windows programmer應該會想到, 可能哪邊搞錯同時把<winsock.h>和<winsock2.h> include進來了, 可是search了一下project, 根本就沒有include到什麼<winsock.h>啊, 而且<winsock2.h>的開頭寫著:
#ifndef _WINSOCK2API_
#define _WINSOCK2API_
#define _WINSOCKAPI_ /* Prevent inclusion of winsock.h in windows.h */
有以上的#define, 應該就不會再去include到<winsock.h>裡面的東西了吧!? 應該是這樣沒錯, 除非......你寫成這樣:
#include <winsock.h>
#include <winsock2.h>
<winsock.h>可沒有什麼預防措施以避免include到<winsock2.h>, 所以這樣的排列就會造成<winsock2.h>裡面的定義全部跟<winsock.h>裡面的衝突。但是, 前面說過了, 我沒有include <winsock.h>啊!! 謎底揭曉了, VC的<windows.h>居然include <winsock.h>......, 而且如果include關係像以下這樣, 那一時之間也很難知道發生什麼問題......
myinc.h的內容
#include <windows.h>
...
main.cpp的內容
#include "myinc.h"
#include <winsock2.h>
main.cpp並沒有include <windows.h>, 是它的include file去include到的, 如果include file很多, 找起來會想撞牆......因此, 最好的方法還是以後都把<winsock2.h>擺最上面好了。
2007年6月7日 星期四
Boost shared_ptr
shared_ptr包含於Boost Smart Pointers裡面, 它可以儲存指標, 並保證在所有存取這個指標的shared_ptr被釋放後, 這個指標所指的記憶體會自動被釋放, 這有很多實用的用途, 例如
當然, return一個heap-allocated object是programmer所應該極力避免的, 因為這是造成memory leak的最危險因素, 但是有時候呢, 還是會碰到需要的情況啊, 例如前人寫的程式已經根深蒂固, 根本沒有辦法修改了, 但是又想避免這種memory leak的可能, 這時候shared_ptr就派上用場了!!
雖然到了最後, 我們還是忘記了c的存在, 但是c已經是個shared_ptr而且是local variable, 所以在foo()的最後, c這個變數會從stack裡消失, 而它所包含的指標所指向的記憶體, 也隨著它的消失而自動的被釋放了, 這世界又變的更簡單一點了。而且, 只需要更改到綠色字體部份的code, 其他code完全不受影響, 因為shared_ptr也overload了->這個operator, 所以操作起來就跟操作原來的指標一樣!!
shared_ptr之所以叫shared_ptr, 也是因為可以有多個shared_ptr包含同一個指標囉, 當然, thread-safe它也有gurantee, 在此就不舉例說明了......
class MyClass {...};
MyClass* getMyClass()
{
return new MyClass();
}
void foo()
{
MyClass *c = getMyClass();
c->foo_1();
// ...
// 做了一堆鳥事
// ...
c->foo_n();
// 最後忘記把c這個pointer delete掉, 造成memory leak, 掯!!
}
當然, return一個heap-allocated object是programmer所應該極力避免的, 因為這是造成memory leak的最危險因素, 但是有時候呢, 還是會碰到需要的情況啊, 例如前人寫的程式已經根深蒂固, 根本沒有辦法修改了, 但是又想避免這種memory leak的可能, 這時候shared_ptr就派上用場了!!
class MyClass {...};
shared_ptr<MyClass> getMyClass()
{
return shared_ptr<MyClass>(new MyClass());
}
void foo()
{
shared_ptr<MyClass> c = getMyClass();
// ...
// ...
c->foo_1();
// 做了一堆鳥事
c->foo_n();
// ...
// ...
// 還是忘記c這個變數的存在...囧
}
雖然到了最後, 我們還是忘記了c的存在, 但是c已經是個shared_ptr而且是local variable, 所以在foo()的最後, c這個變數會從stack裡消失, 而它所包含的指標所指向的記憶體, 也隨著它的消失而自動的被釋放了, 這世界又變的更簡單一點了。而且, 只需要更改到綠色字體部份的code, 其他code完全不受影響, 因為shared_ptr也overload了->這個operator, 所以操作起來就跟操作原來的指標一樣!!
shared_ptr之所以叫shared_ptr, 也是因為可以有多個shared_ptr包含同一個指標囉, 當然, thread-safe它也有gurantee, 在此就不舉例說明了......
2007年6月4日 星期一
Boost C++ Library
Boost當初是由C++委員會核心成員所發起的, 到現在已經是非常成熟穩定的程式庫了!!其中已經有10個library被列入C++ Standard TR1裡面, 陸續還有其他library要進入TR2!!
我的感想啊, Boost真的是C++ programmer一直以來夢寐以求的程式庫
小至能夠取代atoi這些小工具的lexical_cast
大至一整個跨平台的filesystem library
(C或C++在不同平台上的檔案處理真的是會讓人想撞牆XD, 有了Boost Filesystem從此就海闊天空了XDD)
都可以在Boost裡面找到
當然還有一些找不到啦, 例如XML和Logging這兩個常用的東西
有志者可以自己寫一套library去加入Boost喔, 不過要經過層層關卡的review, 沒有毅力恆心者請勿嘗試......
我的感想啊, Boost真的是C++ programmer一直以來夢寐以求的程式庫
小至能夠取代atoi這些小工具的lexical_cast
大至一整個跨平台的filesystem library
(C或C++在不同平台上的檔案處理真的是會讓人想撞牆XD, 有了Boost Filesystem從此就海闊天空了XDD)
都可以在Boost裡面找到
當然還有一些找不到啦, 例如XML和Logging這兩個常用的東西
有志者可以自己寫一套library去加入Boost喔, 不過要經過層層關卡的review, 沒有毅力恆心者請勿嘗試......
2007年5月30日 星期三
Google會不會太猛......
訂閱:
文章 (Atom)