eXile 的专栏

共5页: 1 2 3 4 5 
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
呵呵,也许我没有表达清楚,我说的“局限于native win32的思维方式”,是指局限于win32本身的GUI组件设计,而没有利用OOP技术和模式进行更好的组件与消息封装策略,也就不能消除win32 GUI 设计本身的复杂性。这种设计到顶,也不过是一个改良版的WTL(可以参考 http://www.winxgui.cn/)。当然,它可以适用在性能要求较高的场合,这个,取决于楼主的目标了。
最成熟的 GUI 库当然是Qt, 你的设计还不错,不过感觉还是native win32 的思维方式,没有呈现出更高介的抽象,
re: utf8编码转换 eXile 2008-07-23 23:03
@spirit
我用的mingw, 没有注意到这个问题, 但是由于VC平台的iterator并不是原生指针,所以正确的写法应该是 &ucs2_buf[0]
A:封有什么理由吗?
B:封还需要理由吗?
A: 不需要吗?
B:需要吗?
A: 。。。。研究研究,干吗这么认真呢?
B:熟归熟,乱说话一样告你诽谤。
re: C++代码风格谷歌版 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, 等于没有,
而且这个compressed_pair只是为了优化结构布局,如果在谨慎地使用模板前提下,没有多少价值。
@haskell
无非就是不透明指针或者虚函数
@沙迦
首先搞清楚以下概念:头指针,头结点,首元素指针
对于半同步半异步模式也可以在线程间传递socket描述符来简化处理,但这样业务逻辑就不容易和底层IO脱离, 处理起来要麻烦一些, 我想的也不成熟,欢迎探讨。
BTW,已经找到了 lf.pdf 和 hs-ha.pdf , 看来要研读一下....
谢谢修正,没有看过,不过对于简单的LF模型确实是这样的,因为它可以使用阻塞IO或者单独select,处理起来比较简单。
对ACE的TP_Reactor没有过深研究,boost::asio中的reactor也是‘领导者/跟随者’模式,不过asio并不保证这一点,还得自己加锁
ACE的TP_Reactor 是基于‘领导者/跟随者’模式,这里的探讨主要是针对半同步半异步模式。不过要实现一个无锁的handler,‘领导者/跟随者’模式应该更容易一些。 
re: 剖析Etwork网络库 eXile 2008-05-21 23:04
我也是越来越不喜欢C++了,目前比较倾向于纯C或Python。
对于纯C的网络库,可以试试 libevent 或 libev, 应该算是比较好的库了。
可以参考 boost::asio中的detail/win_fd_set, 很简单
我也碰到过, 通过 '自定义' 菜单可恢复.
我的老是提示末知的IO设备, 不知道是什么东西的驱动不对...
不会吧, cppexplore和我都给你说出错误在哪, 竟然还没有发现....
说到代码规范, 从你这段代码来看, 确实给人印象很差, 比如连续三个过于简写的变量命名, 让人去猜测变量的含义, 这样就不好了.
除了基本的逻辑错误, 象 n && m1 这样的比较, 说明细节不够认真.
说实话, 不象老程序员的作风啊...
@陈梓瀚(vczh)
你所写的模板形式和xpressive的表达式模板并没有太大的差别, 因为表达式模板最终生成的也是类似于这样的东西.
另外, 程序库为了实现功能的全面性和通用性, 必然要损失一部分效率, 楼上的对此也不用大惊小怪, 还是要注意素质.....
lz对链表的实现确实有点问题, 主要是对于链表头结点的管理不对,所以在实现中有些错误.
另外, 面试的题目应该是in place倒置,而不是deep copy, 头结点应该是不变的,所以这个函数根本不应该有返回值, 这个题目本身也不够严谨.
boost::xpressive有两种使用方式, 一种就是和boost::regex一样的动态解析,一种是静态解析,类似于boost::spirit .
如果你使用的正则式是硬编码的字符串(大多数情况下都是如此), 那么使用 xpressive的静态解析具有更高的效率, 因为它的解析模板是在编译期生成的.
楼上的正解。在使用多重继承时要注意对象的布局。
re: MFC之初 eXile 2008-04-23 12:17
@cppexplore
同感。MFC纯粹把C++当成“带类的C”来用,什么面向对象,设计模式统统靠边站。Microsoft的开发人员都是技术大牛,不知道他们对自己设计的MFC作何评价...
re: 模板参数名命名惯例 eXile 2008-04-22 13:19
我觉得作为开源的fans,应该更加注重版权的意识。
re: 两个小巧的开源解析库 eXile 2008-04-16 15:04
tinyxml只适合于读写XML配置文件时使用,虽然简单,但是不满足高效的要求。
re: 对string类的思考 eXile 2008-04-11 17:24
VC6 CString 的字符串也就是常见的引用计数, 象lz这种实现, 再配合一个好用的内存池, 应该是蛮不错的.
re: 单元测试PPT讲义 eXile 2008-04-08 22:56
虽然只是提纲,但讲得还不错!
不知老兄有没有研究过boost::asio的定时器定现, 好象用的也是select
呵呵,一般情况下,你都应该使用any, 而variant为了提高那么一点点效率, 费的那个劲....
如果要提高效率的话, 可以选择 boost::shared_ptr<void>来代替any
.......我来解释一下吧,
any与variant的最大区别在于效率, any内部实现中使用动态分配, 而variant内部使用栈式分配.
variant为对象联合, 比如说variant<int, std::string>, 你可以理解成下列结构: union { int v1; std::string v2; };
re: VC6正在被抛弃 eXile 2008-03-15 13:05
@万连文
其实静多态的优势就是运行效率高一点, 选择静多态还是动多态, 要看插件系统是基于源代码重用,还是二进制重用, 以及对性能的要求如何.
不过一个事实是:不用boost的人,一般对模板都了解不深, 我想这才是这个家伙态度大变的原因吧.
re: GCC4.3... eXile 2008-03-14 13:46
vs2008只有tr1, 并没有实现c++0x, 要到VS10了, 根据MS的发布周期, 估计是VS2011?
在现在gcc的mt_allocator实现中,有一个bug, 就是对一个计数器(_M_use)并没有采用原子计数,这个计数器主要用来控制空闲链的长度,所以它并不会导致程序异常,但是可能会影响到程序性能,不过如果采用原子计数,则有另一个性能上的担忧。这个问题直到最新的gcc4.3中才得到解决。
@cppexplore
谢谢指正,不过cppexplore这么快就把测试模型搞出来,厉害,应该用的是什么库吧,Apache?
这个设计到模板的两次扫描机制,VC或BC的做法可以使编译略微快一些,但是会对一些还没有实例化的模板代码中的语法错误视而不见,而GCC的做法更为稳妥一些,也是符合标准的的行为。
呵呵,正是如此,UserAlloc可以使用一个全局的boost::pool来实现,所谓大pool套小pool, 不过如果object_pool设计时完全放弃destroy, 则可以取得更大的优化。
这个倒不是问题,因为object_pool是可配置的, 它带有一个模板参数UserAlloc, 可以自定义
呵呵,不当之处,敬请原谅。
“多次申请,一次释放”的情况,比如说对于服务器而言,从收到一个包,到对这个包的处理完毕,则可视为内存的一个周期。不过有时候异步完成,再加上object_pool只能管理一种对象,又限制了这种使用。
数据拷贝是不可避免的,而且一般对效率影响不大,主要还是内存管理上作一些优化,比如使用内存池。
我觉得lz对object_pool 的设计理念和如何使用都存在理解上的错误, 特别是以下几点:
1) 构造函数只能执行默认构造函数
2) 设计了destroy这个函数,而同时为了防止用户遗漏掉这个调用,而又在内存池析构的时候进行了检测回收
3)为了这个目的而又不至于析构object_pool的时间复杂度是O(n平方)


object_pool 主要着眼于“自动析构”,在没有gc的情况下,达到提高效率和自动管理内存的目的。而且它也特别适合于“多次申请,一次释放”的情况.所以它甚至是鼓励你忽略使用destroy(从它的例子就可以看出来)。

destroy函数并没有提高复杂度,因为内部链表始终处于有序状态(由于使用order_malloc,order_free),所以不论是逐个释放,还是成批释放,它的复杂度都是O(N)

对于最后一个AutoFreeAlloc, 我碰巧也研究过, 其实对于你说的"没有pool回收到allocator,以供下次继续使用"的问题,它最近的实现中已经解决了.
在c++ 标准库实现SGI STL中还有一种内存池的实现, 就是用一系列固定长的内存池来实现一个不定长的内存池, 它曾经是gcc3中stl的默认实现, 但在gcc4中不再使用, 理由是在多线程情况下优化并不明显, 线程锁反而成为瓶颈. 所以有时候一个线程一个内存池也是一个选择.
@WXX
其实lz所说的结构体指的把网络数据看作是POD数据类型来处理, 这样来简化处理过程(当然在我看来, 这只能把处理过程搞得更复杂), 而序列化把网络数据看作二进制流或文本流. 从这个角度来谈论这个问题的.
其实你的设计就是最简单的序列化实现.
不过用较好的序列化库对于接收时就简单多了:

std::vector<std::string> user_names;
in_archive ar(received_data, received_size);
if (ar.serialize(user_names)) visit(user_names);

在serialize函数里包含了各种异常情况处理, 比如错误的数据, 字符串长度异常,而像你的要完全自己处理, 那太复杂了, 这正是我所说的容易产生bug的地方.
呵呵, 那就具体探讨一下, 比如发送一个用户名列表, 这是一个字符串的容器, 用序列化大致实现起来就是以下样子:
std::vector<std::string> user_names;
archive ar;
if (ar.serialize(user_names)) socket.send(ar.data(), ar.size());

不知道你是怎么实现的, 欢迎探讨.
缺点就是拐弯抹角,代码量大?
我的结论恰恰相反, 使用序列化的最大好处是简化编程, 以及将来的可扩展性,
至于调试, 对于这种网络程序,如果再加上多线程,是很难调试的,而这种你所说的结构体简直是bug的温床, 所以为了保证可靠性,一般都是用命令录制回放来进行测试的.
一定要有typename, 不然通不过编译....
刚才试了一下, 没有问题, 我用的是VC2005 (SP1)
正确的写法,使用template关键字,应该改成这样:

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的,你跟人家宣传这个。。。
我的做法是为配置设定默认值,如果读写失败,就取默认值。
共5页: 1 2 3 4 5 

导航

<2008年4月>
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910

统计

常用链接

留言簿(18)

随笔分类

随笔档案

服务器编程

搜索

最新评论

阅读排行榜

评论排行榜