C++
小鸡射手
这个作者很懒,什么都没留下…
展开
-
C++的对象互斥访问
对象的互斥访问,C#有lock关键字,Java有synchronized关键字,Windows下的C++就只有通过CriticalSection API自己编程实现了。下面是小鸡射手的Mutex类: class Mutex { public: Mutex() {InitializeCriticalSection(&m_cs);} virtu原创 2004-07-02 07:21:00 · 1824 阅读 · 5 评论 -
TProactor
ACE Proactor模式在Windows性能很好,在Unix/Linux下由于各版本对异步IO支持的不同,ACE Proactor实现的性能不一定好(有的是采用Thread模拟异步IO)。 Terabit的POSIX Proactor实现TProactor在Windows、Unix/Linux下采用一致的接口,并在任何操作系统下提供不低于TPReactor的性能。原创 2009-05-17 09:47:00 · 2077 阅读 · 0 评论 -
C++图书阅读进阶
C++图书阅读进阶: 1) C++ Primer Plus或Thinking in C++,学习C++基础知识 2) The C++ Standard Library A Tutorial and Reference,学习stl基础知识 3) Effective C++、More Effective C++、Exceptional C++、 More Exceptional C++、E原创 2009-05-30 20:08:00 · 556 阅读 · 0 评论 -
Effective C++之十四
主题:仔细考虑资源管理类的复制行为。 不是所有的资源都是在堆上分配,这样就无法使用条款13。Meyers通过Mutex类例子,提出一个问题:如何定义资源管理类的复制行为? 大多数情况下,可采用以下方案之一: 1) 禁止复制。想mutex之类的同步类,就不应该负责; 2) 对底层资源进行引用计数。如果Lock采用引原创 2009-06-07 12:32:00 · 254 阅读 · 0 评论 -
Effective C++之十五
主题:资源管理类中提供直接访问底层资源的机制。 资源管理类能防止资源泄漏。理想情况下,我们均采用资源管理类与底层资源交互。但是,许多API需要直接访问底层资源,所以需要提供直接访问底层资源的机制。 有两个方法将资源管理类转换为底层资源:显式转换(explicit conversion)和隐式转换(implicit conversion)。原创 2009-06-07 13:32:00 · 237 阅读 · 0 评论 -
Effective C++之十七
要点:必须在单独语句中将newed对象保存于智能指针。 Meyers举了这样的例子:processWidget(std::tr1::shared_ptr(new Widget), priority()); 以上语句可能发生问题的原因是:C++编译计算表达式的顺序不是固定的。如果processWidget函数计算参数的顺序是: 1) n原创 2009-06-07 14:00:00 · 267 阅读 · 0 评论 -
Effective C++之十三
核心思想:采用对象管理资源。 Meyers通过Investment类说明了3种因没有delete造成资源泄漏的情况: 1) delete前return了 2) cretaeInvesetment和delete在循环中,在循环中某处continue、break或goto了 3) delete前发生了异常。 可以采用st原创 2009-06-07 11:49:00 · 254 阅读 · 0 评论 -
Effective C++之十六
核心思想:new和delete,new[]和delete[]对应使用。 如果错误地使用,将会产生未定义的行为。Meyers提到,当使用了typedef之后,要特别注意此问题。 附:推荐使用boost::checked_delete和boost::checked_array_delete,当编译器发现delete一个未完全定义(an incomplete原创 2009-06-07 13:47:00 · 279 阅读 · 0 评论 -
Effective C++之十八
要点:防止客户错误使用接口的方法。 C++有函数接口、类接口和模板接口。理想情况下,如果使用接口无法实现客户期望的功能,则代码应无法通过编译;如果代码能通过编译,则应完成客户期望的功能。 设计不易出错的接口时需考虑客户可能会犯的错误,Meyers举了Date的例子。许多错误可以通过增加新的类型来防止,另一个方法是对类型进行限制,例如增加const。一致性是接原创 2009-06-17 10:57:00 · 241 阅读 · 0 评论 -
Effective C++之十九
要点:设计类时需要考虑的问题。 在C++中,设计类就是定义类型。重载函数和算符、分配释放内存、对象初始化结束等,均由设计者处理。设计优秀的类极具挑战性,它必须具备自然的语法、明确的语义及高效的实现。 每个类都要面对以下问题: - 对象如何创建和销毁?它将影响构造、析构以及内存管理函数 - 对象初始化和赋值的差别是什么?原创 2009-06-17 11:18:00 · 211 阅读 · 0 评论 -
Effective C++之二十
要点:优先使用const引用传递参数,而不是传值。 C++缺省的参数传递方式是传值。通过const引用传递参数要高效得多,因为它不再调用copy构造和析构函数。通过引用传递参数还可以解决切割(slicing)问题,当子类作为基类对象传递参数时,仅调用基类的copy构造函数,其子类部分被切割掉了。 对于内置的类型,传值更高效。传值同样适用于STL的迭代器和函数对象原创 2009-06-17 13:23:00 · 242 阅读 · 0 评论 -
Effective C++之二十一
核心思想:返回对象时不要返回引用。 Meyers举了有理数的例子,说明返回定义在堆栈上对象的引用,将导致错误。采用静态变量也不是解决问题的方法。 因此,不要返回指向堆栈的指针和引用,而是应该返回对象。原创 2009-06-17 13:46:00 · 235 阅读 · 0 评论 -
Effective C++之二十六
要点:尽量延迟变量定义。 定义类变量是有开销的,定义时的构造和出了作用域后的析构。因此,应该尽量迟地定义变量。 进而,应该尽可能迟到该变量有初始化时定义;因为一般的,一次copy构造的开销小于一次确省构造 + 一次赋值函数调用。 对于有循环的情况,在循环内还是循环外定义变量,与构造、析构、赋值的开销以及循环次数n有关。Meyer是特别提出在循环原创 2009-06-20 15:09:00 · 262 阅读 · 0 评论 -
Efective C++之三十
要点:理解inline的有缺点。 inline的基本想法就是用代码体取代函数调用。显然,这会增加代码大小,导致更多的页面交换、更低的缓存击中率等等。如果代码体小于函数调用代码,那inline导致代码更小、缓存击中率更高。 inline对编译器而言,只是建议,编译器不一定真的inline。定义inline有两种方式,在函数定义时隐式定义(通常是成员函数,也可以原创 2009-06-20 20:14:00 · 457 阅读 · 0 评论 -
Effective C++之二十五
要点:提供不会抛出异常的swap函数。 swap自STL引入后就成为异常安全(exception-safe)编程的基石。在条款11避免自赋值时已谈到过。 STL中swap的缺省实现是通过临时变量实现交换。但是对某些类型这是很低效的,例如pimpl只需要交换指针即可。 之后,Meyers提出在std命名空间内特例化函数模板swap的实现。由于函数原创 2009-06-20 15:01:00 · 496 阅读 · 0 评论 -
Effective C++之二十九
要点:争取写异常安全的代码。 Meyers通过PrettyMenu::changeBackground的例子,指出异常发生时可能发生的问题: 1) Mutex的资源泄漏 2) 没有new成功就改变了imageChanges 3) bgImage指针状态错误,指向已删除的内存。 从而引出异常安全函数的三种保证:原创 2009-06-20 20:06:00 · 314 阅读 · 0 评论 -
Effective C++之二十二
要点:将成员变量声明为private。 有以下理由: 1) 接口语法的一致性。所有接口都是函数,均需() 2) 对成员变量访问的精确控制。例如不可直接访问、只读、读写 3) 封装性。首先能确保类的不变量( invariants),而且保留修改实现的权利,例如可以采用计算来替代成员变量。 protected成员变量的封装原创 2009-06-20 11:35:00 · 247 阅读 · 0 评论 -
Effective C++之二十三
要点:优先考虑非成员非友元函数。 通过Browser类的clearBrowser函数,Meyers指出面向对象原则建议成员函数更好是不正确的。理由如下: - 面向对象原则要求数据尽可能地封装 - 对成员变量而言,能访问它的代码越少,封装性更好,也更容易修改 - 从粗颗粒度的度量,封装性与可访数据的函数(成员函数、友元函数)个数成反比原创 2009-06-20 12:04:00 · 261 阅读 · 0 评论 -
google V8 process.cc示例
google V8引擎的示例代码process.cc,核心类是JsHttpRequestProcessor。 Initialize()函数完成以下功能: - 设置全局javascript日志函数log的C++实现(155行) - InstallMaps中将C++ map的options(602行)和output(616行)作为js全局变量optio原创 2009-04-01 18:12:00 · 823 阅读 · 0 评论 -
Effective C++之十一
原创 2008-11-22 19:01:00 · 220 阅读 · 0 评论 -
Effective C++之八
要点:不要在析构函数中抛出异常。 Mayers举了一个Widgets vector例子:如果第一个元素的析构函数中抛出了异常,为了避免资源泄漏等问题,其他元素也需要析构,假设第二个元素的析构函数又抛出一个异常。C++无法同时处理两个异常,将导致未知行为甚至程序终止。 补充一个例子:函数执行中抛出异常,退出该函数前将析构所有局部对象。如果在析构局部对象时又抛出异常,也将面原创 2008-11-22 15:56:00 · 233 阅读 · 0 评论 -
Singleton实现的反思
Singleton可算是最简单的模式,本文记述小鸡射手遇到的问题及反思。 对于Singleton,小鸡射手想能不能: 1. 将private static成员变量直接声明为Singleton类? 2. 将要调用的方法直接声明为static? 在项目中,采用VC++按方式1实现Singleton类,编译、链接一切OK。运行时却出现了内存方面的exception,经调原创 2004-07-13 19:59:00 · 1261 阅读 · 0 评论 -
C/C++中export的定义
Windows下的DLL、Linux下的库或是C++中调用C的库,均可能用到import/export。本文讨论一种通用的import/export宏定义的使用实践。 如下所示,"common.h"定义了可以跨平台的import/export宏定义,"something.h"定义了某个类头文件的import/export定义,"something.cpp"实现类并ex原创 2004-07-06 06:48:00 · 2248 阅读 · 0 评论 -
采用ACE实现C++中的Plugin
本文描述小鸡射手采用ACE的Service Configurator Framework实现C++的plugin机制。 首先,定义一个export头文件,可以从/examples/APG/Svc_Config的HASTATUS_export.h复制修改。头文件定义如下:#include "ace/OS.h"#include "ace/Service_O原创 2007-02-06 16:01:00 · 1930 阅读 · 1 评论 -
重写日志库的感悟
如服务器软件中所述,对于一个需要长期运行的服务器程序,日志功能必不可少。服务器端通用日志库的需求包括:- 灵活的日志策略- 因为用于实时程序,需要后台线程写日志- 对于有界面程序,需要在用户界面显示日志;对于daemon程序,需要通过socket将日志发送给监控程序。 原有的日志库存在以下问题:- 写文件、控制格式、文件大小等都是自己编码的。日志策略不够灵活,历史久远无人维原创 2007-02-08 19:28:00 · 1178 阅读 · 0 评论 -
服务器端软件的一种设计
服务器端软件的复杂度相对比较高。30000多行代码的中间件软件的主线程程序又是怎样的呢? 小鸡射手在实际工作中设计的网络服务的主线程代码如下:IContext& context = ContextManager::GetContext();IEventHandler& handler = EventHandlerManager::GetEventHandl原创 2007-01-02 18:18:00 · 890 阅读 · 0 评论 -
const
Use const whenever possible,这是Effective C++第三条。此外,再记录几点: - 在定义pure virtual function时,要慎用const,因为尚不清楚子类的实现; - const有时可以写在类型前面,也可以写在后面,按《C++ Template》的说法,建议写在后面,以一致表达普通类型和指针类型,特别是模板类的话;原创 2008-09-15 20:00:00 · 242 阅读 · 0 评论 -
Pclint统计小工具
Pclint是一个很不错的C/C++静态分析工具。 用Ruby写了一个统计小工具,统计每个子目录、文件中错误/告警数,各类错误/告警总数。 功能还比较单纯,期望未来能记录数据库,并结合PSP概念,成为更有效的工具。 没有找到上传文件的地方,可留下email。原创 2008-11-02 09:03:00 · 598 阅读 · 1 评论 -
Effective C++ 之一
原创 2008-11-02 09:23:00 · 390 阅读 · 1 评论 -
Effective C++之二
第二条的内容记忆得就不如第一条丰富了,:-) 核心思想:不要使用#define! 一般的,#define有两个用途:1. 定义常量,2.定义常用操作,例如max(a,b)。 #define用途一的替代方案是:const变量。好处一是:宏定义是预编译处理的,只是做简单的文本替换,宏定义token不在编译符号表支持,而const能在编译期检查类型。好处二是,C原创 2008-11-02 10:05:00 · 334 阅读 · 0 评论 -
Effective C++之三
主题:尽可能使用const。 const运用范围很广:全局常量、类内常量、静态常量、输入参数常量、返回值常量、函数常量。声明为常量后,编译器会检查其常量性。对指针,const可用于说明指针本身、指针指向内容、两者都是常量。对指针指向内容的cosnt,C++语法支持两种语法(参见Widget例子);我个人习惯于写在左边,但是考虑到写template时的一致性,《C++ Temp原创 2008-11-02 10:31:00 · 430 阅读 · 0 评论 -
Effective C++之四
核心思想:对象使用前必须初始化。 C++对象初始化没有简明的规则。大致而已,出于效率考虑,C++的C部分(参见条款1)不保证进行初始化,而非C的部分能保证初始化。读取未初始化的随机值,将导致未定义的行为,包括程序异常退出。 最好的做法是:在使用前永远进行初始化,对内置数据类型进行手工初始化。 对于对象而已,初始化的职责落在构造函数上。成员变量初始化原创 2008-11-15 11:30:00 · 282 阅读 · 0 评论 -
Effective C++之五
重点:了解C++自动合成和调用的缺省构造、Copy构造、赋值和析构函数。 即使你定义了一个空类,C++编译器也会为你生成上述函数。准确地说,是在需要的时候生成。见而言之,它们做以下工作: - 缺省构造和析构,调用基类和成员对象的缺省构造和析构函数 - copy构造和赋值操作,简单地复制每一个成员对象的值。对于基本类型,就是bitwise复制。原创 2008-11-15 12:51:00 · 254 阅读 · 0 评论 -
Effective C++之六
要点:显示禁止不想使用的编译器合成函数。 条款5中叙述了编译器可能合成四类函数。在某些情况下,如作者例子中“要出售房屋”实例,不希望有Copy构造和赋值操作。补充例子:Singleton模式。 有两种做法: 1) 将Copy构造和赋值操作声明为private,不提供函数实现。 1.1 声明Copy构造和赋值操作后,编译器不会再合成原创 2008-11-22 13:27:00 · 241 阅读 · 0 评论 -
Effective C++之七
原创 2008-11-22 13:56:00 · 208 阅读 · 0 评论 -
Effective C++之九
要点:不要在构造/析构函数中调用虚函数。 原因是: 1) 子类构造函数首先调用基类构造函数,故在运行基类构造函数时,子类成员变量尚未初始化 2) 更重要的是,在调用基类构造函数时,对象的类型是基类类型。不但虚函数认为(resolve to)基类函数,运行时类型(Runtime Type Information)也认为是基类。 析构函数也是同原创 2008-11-22 16:16:00 · 210 阅读 · 0 评论 -
Effective C++之十
要点: 赋值操作返回*this的引用。 其作用是支持连续赋值,例如:x = y = z = 15; 这只是一种惯用法(convention),如果不这么写编译还是能通过的。 最后,除了标准赋值操作外,其他赋值操作(+=、*=等等)均适用。原创 2008-11-22 18:53:00 · 222 阅读 · 0 评论 -
Effective C++之十二
核心思想:Copy构造和赋值操作中,复制对象的所有部分。设计良好的类封装了内部状态,只有两个复制函数:Copy构造函数和赋值操作函数。条款5中谈了编译器合成的复制函数。当类中声明了Copy构造函数和赋值操作函数,即使有明显逻辑错误,编译器也不会报错。Mayers举了Customer类的例子:如果类中增加了新的成员变量,而没有更新相关复制函数,复制函数只复制对象的部分。有继承时问题更隐蔽原创 2008-11-24 07:08:00 · 245 阅读 · 0 评论 -
Effective C++之二十四
要点:所有参数需要隐式类型转换时,请采用非成员函数。 使用隐式类型转换往往不是一个好主意,一个例外是定义数据类型时。Meyers举了有理数乘法的例子,说明:只有在参数列表中才能进行隐式类型转换,因此需要乘法操作定义为非成员函数。 Meyers特别探讨了,非成员函数不一定是对应类的友元函数。很多程序员认为与类相关的非成员函数应该是友元函数的观念是错误的。应尽可能避原创 2009-06-20 13:11:00 · 248 阅读 · 0 评论