Qt中可以采用 QSignalMapper.
void numberClicked(int id) {}
QPushButton* button0;
QPushButton* button1;
QSignalMapper* map = new QSignalMapper(this);
connect(button0, SIGNAL(clicked()), signalMapper, SLOT(map()));
connect(button1, SIGNAL(clicked()), signalMapper, SLOT(map()));
map->setMapping(button0, 0);
map->setMapping(button1, 1);
connect(map, SIGNAL(mapped(int)), this, SIGNAL(numberClicked(id)));
@cexer
呵呵,也許我沒有表達(dá)清楚,我說的“局限于native win32的思維方式”,是指局限于win32本身的GUI組件設(shè)計(jì),而沒有利用OOP技術(shù)和模式進(jìn)行更好的組件與消息封裝策略,也就不能消除win32 GUI 設(shè)計(jì)本身的復(fù)雜性。這種設(shè)計(jì)到頂,也不過是一個(gè)改良版的WTL(可以參考
http://www.winxgui.cn/)。當(dāng)然,它可以適用在性能要求較高的場(chǎng)合,這個(gè),取決于樓主的目標(biāo)了。
最成熟的 GUI 庫(kù)當(dāng)然是Qt, 你的設(shè)計(jì)還不錯(cuò),不過感覺還是native win32 的思維方式,沒有呈現(xiàn)出更高介的抽象,
re: utf8編碼轉(zhuǎn)換 eXile 2008-07-23 23:03
@spirit
我用的mingw, 沒有注意到這個(gè)問題, 但是由于VC平臺(tái)的iterator并不是原生指針,所以正確的寫法應(yīng)該是 &ucs2_buf[0]
A:封有什么理由嗎?
B:封還需要理由嗎?
A: 不需要嗎?
B:需要嗎?
A: 。。。。研究研究,干嗎這么認(rèn)真呢?
B:熟歸熟,亂說話一樣告你誹謗。
re: C++代碼風(fēng)格谷歌版 eXile 2008-07-01 17:59
@true
we only allow an approved subset of Boost features. Currently, only boost/compressed_pair.hpp is permitted
目前,只允許使用 boost/compressed_pair.hpp, 等于沒有,
而且這個(gè)compressed_pair只是為了優(yōu)化結(jié)構(gòu)布局,如果在謹(jǐn)慎地使用模板前提下,沒有多少價(jià)值。
對(duì)于半同步半異步模式也可以在線程間傳遞socket描述符來簡(jiǎn)化處理,但這樣業(yè)務(wù)邏輯就不容易和底層IO脫離, 處理起來要麻煩一些, 我想的也不成熟,歡迎探討。
BTW,已經(jīng)找到了 lf.pdf 和 hs-ha.pdf , 看來要研讀一下....
謝謝修正,沒有看過,不過對(duì)于簡(jiǎn)單的LF模型確實(shí)是這樣的,因?yàn)樗梢允褂米枞桑匣蛘邌为?dú)select,處理起來比較簡(jiǎn)單。
對(duì)ACE的TP_Reactor沒有過深研究,boost::asio中的reactor也是‘領(lǐng)導(dǎo)者/跟隨者’模式,不過asio并不保證這一點(diǎn),還得自己加鎖
ACE的TP_Reactor 是基于‘領(lǐng)導(dǎo)者/跟隨者’模式,這里的探討主要是針對(duì)半同步半異步模式。不過要實(shí)現(xiàn)一個(gè)無鎖的handler,‘領(lǐng)導(dǎo)者/跟隨者’模式應(yīng)該更容易一些?!?/div>
我也是越來越不喜歡C++了,目前比較傾向于純C或Python。
對(duì)于純C的網(wǎng)絡(luò)庫(kù),可以試試 libevent 或 libev, 應(yīng)該算是比較好的庫(kù)了。
可以參考 boost::asio中的detail/win_fd_set, 很簡(jiǎn)單
我也碰到過, 通過 '自定義' 菜單可恢復(fù).
我的老是提示末知的IO設(shè)備, 不知道是什么東西的驅(qū)動(dòng)不對(duì)...
不會(huì)吧, cppexplore和我都給你說出錯(cuò)誤在哪, 竟然還沒有發(fā)現(xiàn)....
說到代碼規(guī)范, 從你這段代碼來看, 確實(shí)給人印象很差, 比如連續(xù)三個(gè)過于簡(jiǎn)寫的變量命名, 讓人去猜測(cè)變量的含義, 這樣就不好了.
除了基本的邏輯錯(cuò)誤, 象 n && m1 這樣的比較, 說明細(xì)節(jié)不夠認(rèn)真.
說實(shí)話, 不象老程序員的作風(fēng)啊...
@陳梓瀚(vczh)
你所寫的模板形式和xpressive的表達(dá)式模板并沒有太大的差別, 因?yàn)楸磉_(dá)式模板最終生成的也是類似于這樣的東西.
另外, 程序庫(kù)為了實(shí)現(xiàn)功能的全面性和通用性, 必然要損失一部分效率, 樓上的對(duì)此也不用大驚小怪, 還是要注意素質(zhì).....
lz對(duì)鏈表的實(shí)現(xiàn)確實(shí)有點(diǎn)問題, 主要是對(duì)于鏈表頭結(jié)點(diǎn)的管理不對(duì),所以在實(shí)現(xiàn)中有些錯(cuò)誤.
另外, 面試的題目應(yīng)該是in place倒置,而不是deep copy, 頭結(jié)點(diǎn)應(yīng)該是不變的,所以這個(gè)函數(shù)根本不應(yīng)該有返回值, 這個(gè)題目本身也不夠嚴(yán)謹(jǐn).
boost::xpressive有兩種使用方式, 一種就是和boost::regex一樣的動(dòng)態(tài)解析,一種是靜態(tài)解析,類似于boost::spirit .
如果你使用的正則式是硬編碼的字符串(大多數(shù)情況下都是如此), 那么使用 xpressive的靜態(tài)解析具有更高的效率, 因?yàn)樗慕馕瞿0迨窃诰幾g期生成的.
樓上的正解。在使用多重繼承時(shí)要注意對(duì)象的布局。
re: MFC之初 eXile 2008-04-23 12:17
@cppexplore
同感。MFC純粹把C++當(dāng)成“帶類的C”來用,什么面向?qū)ο螅O(shè)計(jì)模式統(tǒng)統(tǒng)靠邊站。Microsoft的開發(fā)人員都是技術(shù)大牛,不知道他們對(duì)自己設(shè)計(jì)的MFC作何評(píng)價(jià)...
re: 模板參數(shù)名命名慣例 eXile 2008-04-22 13:19
我覺得作為開源的fans,應(yīng)該更加注重版權(quán)的意識(shí)。
re: 兩個(gè)小巧的開源解析庫(kù) eXile 2008-04-16 15:04
tinyxml只適合于讀寫XML配置文件時(shí)使用,雖然簡(jiǎn)單,但是不滿足高效的要求。
re: 對(duì)string類的思考 eXile 2008-04-11 17:24
VC6 CString 的字符串也就是常見的引用計(jì)數(shù), 象lz這種實(shí)現(xiàn), 再配合一個(gè)好用的內(nèi)存池, 應(yīng)該是蠻不錯(cuò)的.
re: 單元測(cè)試PPT講義 eXile 2008-04-08 22:56
雖然只是提綱,但講得還不錯(cuò)!
不知老兄有沒有研究過boost::asio的定時(shí)器定現(xiàn), 好象用的也是select
呵呵,一般情況下,你都應(yīng)該使用any, 而variant為了提高那么一點(diǎn)點(diǎn)效率, 費(fèi)的那個(gè)勁....
如果要提高效率的話, 可以選擇 boost::shared_ptr<void>來代替any
.......我來解釋一下吧,
any與variant的最大區(qū)別在于效率, any內(nèi)部實(shí)現(xiàn)中使用動(dòng)態(tài)分配, 而variant內(nèi)部使用棧式分配.
variant為對(duì)象聯(lián)合, 比如說variant<int, std::string>, 你可以理解成下列結(jié)構(gòu): union { int v1; std::string v2; };
re: VC6正在被拋棄 eXile 2008-03-15 13:05
@萬連文
其實(shí)靜多態(tài)的優(yōu)勢(shì)就是運(yùn)行效率高一點(diǎn), 選擇靜多態(tài)還是動(dòng)多態(tài), 要看插件系統(tǒng)是基于源代碼重用,還是二進(jìn)制重用, 以及對(duì)性能的要求如何.
不過一個(gè)事實(shí)是:不用boost的人,一般對(duì)模板都了解不深, 我想這才是這個(gè)家伙態(tài)度大變的原因吧.
re: GCC4.3... eXile 2008-03-14 13:46
vs2008只有tr1, 并沒有實(shí)現(xiàn)c++0x, 要到VS10了, 根據(jù)MS的發(fā)布周期, 估計(jì)是VS2011?
re: 高性能服務(wù)器的多線程策略 eXile 2008-03-12 12:41
在現(xiàn)在gcc的mt_allocator實(shí)現(xiàn)中,有一個(gè)bug, 就是對(duì)一個(gè)計(jì)數(shù)器(_M_use)并沒有采用原子計(jì)數(shù),這個(gè)計(jì)數(shù)器主要用來控制空閑鏈的長(zhǎng)度,所以它并不會(huì)導(dǎo)致程序異常,但是可能會(huì)影響到程序性能,不過如果采用原子計(jì)數(shù),則有另一個(gè)性能上的擔(dān)憂。這個(gè)問題直到最新的gcc4.3中才得到解決。
re: 高性能服務(wù)器的多線程策略 eXile 2008-03-06 22:36
@cppexplore
謝謝指正,不過cppexplore這么快就把測(cè)試模型搞出來,厲害,應(yīng)該用的是什么庫(kù)吧,Apache?
re: GCC不能正確繼承模板類? eXile 2008-03-03 13:48
這個(gè)設(shè)計(jì)到模板的兩次掃描機(jī)制,VC或BC的做法可以使編譯略微快一些,但是會(huì)對(duì)一些還沒有實(shí)例化的模板代碼中的語(yǔ)法錯(cuò)誤視而不見,而GCC的做法更為穩(wěn)妥一些,也是符合標(biāo)準(zhǔn)的的行為。
呵呵,正是如此,UserAlloc可以使用一個(gè)全局的boost::pool來實(shí)現(xiàn),所謂大pool套小pool, 不過如果object_pool設(shè)計(jì)時(shí)完全放棄destroy, 則可以取得更大的優(yōu)化。
這個(gè)倒不是問題,因?yàn)閛bject_pool是可配置的, 它帶有一個(gè)模板參數(shù)UserAlloc, 可以自定義
呵呵,不當(dāng)之處,敬請(qǐng)?jiān)彙?
“多次申請(qǐng),一次釋放”的情況,比如說對(duì)于服務(wù)器而言,從收到一個(gè)包,到對(duì)這個(gè)包的處理完畢,則可視為內(nèi)存的一個(gè)周期。不過有時(shí)候異步完成,再加上object_pool只能管理一種對(duì)象,又限制了這種使用。
數(shù)據(jù)拷貝是不可避免的,而且一般對(duì)效率影響不大,主要還是內(nèi)存管理上作一些優(yōu)化,比如使用內(nèi)存池。
我覺得lz對(duì)object_pool 的設(shè)計(jì)理念和如何使用都存在理解上的錯(cuò)誤, 特別是以下幾點(diǎn):
1) 構(gòu)造函數(shù)只能執(zhí)行默認(rèn)構(gòu)造函數(shù)
2) 設(shè)計(jì)了destroy這個(gè)函數(shù),而同時(shí)為了防止用戶遺漏掉這個(gè)調(diào)用,而又在內(nèi)存池析構(gòu)的時(shí)候進(jìn)行了檢測(cè)回收
3)為了這個(gè)目的而又不至于析構(gòu)object_pool的時(shí)間復(fù)雜度是O(n平方)
object_pool 主要著眼于“自動(dòng)析構(gòu)”,在沒有g(shù)c的情況下,達(dá)到提高效率和自動(dòng)管理內(nèi)存的目的。而且它也特別適合于“多次申請(qǐng),一次釋放”的情況.所以它甚至是鼓勵(lì)你忽略使用destroy(從它的例子就可以看出來)。
destroy函數(shù)并沒有提高復(fù)雜度,因?yàn)閮?nèi)部鏈表始終處于有序狀態(tài)(由于使用order_malloc,order_free),所以不論是逐個(gè)釋放,還是成批釋放,它的復(fù)雜度都是O(N)
對(duì)于最后一個(gè)AutoFreeAlloc, 我碰巧也研究過, 其實(shí)對(duì)于你說的"沒有pool回收到allocator,以供下次繼續(xù)使用"的問題,它最近的實(shí)現(xiàn)中已經(jīng)解決了.
在c++ 標(biāo)準(zhǔn)庫(kù)實(shí)現(xiàn)SGI STL中還有一種內(nèi)存池的實(shí)現(xiàn), 就是用一系列固定長(zhǎng)的內(nèi)存池來實(shí)現(xiàn)一個(gè)不定長(zhǎng)的內(nèi)存池, 它曾經(jīng)是gcc3中stl的默認(rèn)實(shí)現(xiàn), 但在gcc4中不再使用, 理由是在多線程情況下優(yōu)化并不明顯, 線程鎖反而成為瓶頸. 所以有時(shí)候一個(gè)線程一個(gè)內(nèi)存池也是一個(gè)選擇.
@WXX
其實(shí)lz所說的結(jié)構(gòu)體指的把網(wǎng)絡(luò)數(shù)據(jù)看作是POD數(shù)據(jù)類型來處理, 這樣來簡(jiǎn)化處理過程(當(dāng)然在我看來, 這只能把處理過程搞得更復(fù)雜), 而序列化把網(wǎng)絡(luò)數(shù)據(jù)看作二進(jìn)制流或文本流. 從這個(gè)角度來談?wù)撨@個(gè)問題的.
其實(shí)你的設(shè)計(jì)就是最簡(jiǎn)單的序列化實(shí)現(xiàn).
不過用較好的序列化庫(kù)對(duì)于接收時(shí)就簡(jiǎn)單多了:
std::vector<std::string> user_names;
in_archive ar(received_data, received_size);
if (ar.serialize(user_names)) visit(user_names);
在serialize函數(shù)里包含了各種異常情況處理, 比如錯(cuò)誤的數(shù)據(jù), 字符串長(zhǎng)度異常,而像你的要完全自己處理, 那太復(fù)雜了, 這正是我所說的容易產(chǎn)生bug的地方.
呵呵, 那就具體探討一下, 比如發(fā)送一個(gè)用戶名列表, 這是一個(gè)字符串的容器, 用序列化大致實(shí)現(xiàn)起來就是以下樣子:
std::vector<std::string> user_names;
archive ar;
if (ar.serialize(user_names)) socket.send(ar.data(), ar.size());
不知道你是怎么實(shí)現(xiàn)的, 歡迎探討.
缺點(diǎn)就是拐彎抹角,代碼量大?
我的結(jié)論恰恰相反, 使用序列化的最大好處是簡(jiǎn)化編程, 以及將來的可擴(kuò)展性,
至于調(diào)試, 對(duì)于這種網(wǎng)絡(luò)程序,如果再加上多線程,是很難調(diào)試的,而這種你所說的結(jié)構(gòu)體簡(jiǎn)直是bug的溫床, 所以為了保證可靠性,一般都是用命令錄制回放來進(jìn)行測(cè)試的.
一定要有typename, 不然通不過編譯....
剛才試了一下, 沒有問題, 我用的是VC2005 (SP1)
正確的寫法,使用template關(guān)鍵字,應(yīng)該改成這樣:
template<class ThreadingModel>
struct pool : private ThreadingModel
{
typedef typename ThreadingModel::template thread_safe_type<size_t>::result index_t;
//other public members
private:
index_t first_free_;
};
Cavendish Qi 是Trolltech的,你跟人家宣傳這個(gè)。。。
re: 濫用ini配置文件造成崩潰 eXile 2008-01-29 12:59
我的做法是為配置設(shè)定默認(rèn)值,如果讀寫失敗,就取默認(rèn)值。