|
泛型 :基于策略的basic_string实现(5) 这是一个例子——实例化。 typedef flex_string< char, std::char_traits<char>, std::allocator<char>, SmallStringOpt<char, 16, VectorStringStorage<char, std::allocator<char> > > > String; 这指定了一个字符串,使用基于std::vector的存储和对16个字符以下的小字符串采取优化 回到COW 不管你是否喜欢,你不能忽略COW——太多人觉得它有用。为了这些人,我们来实现一个CowString模板类,这个模板类也能把COW特性加到其他Storage中去。CowString是这样的: template <class E, class Storage> class CowString P Struct Data { Storage s_; Unsigned int refs_; }; Data* pData_; Public: .. .. }; Data保存任何你选定的Storage加上一个引用计数器。CowString本身只包含一个Data指针,多个CowString可能会指向同一个Data对象。当Data可能发生改变时,CowString制造一个它data的真正复制。 现在来看看这个: typedef flex_string< char, std::char_traits<char>, std_allocator<char>, SmallStringOpt<char, 5, CowString<char, AllocatorStringStorage<char, std::allocator<char> > > > > String 现在我们得到一个字符串,它对小于五字节字符串不采用动态分配。对长字符串,使用COW策略,而这个COW策略又是建立在基于分配器的实现之上。 CowString再次使flex_string的可能实例加倍,所以我们现在有十二个实现供我们支配,代码总数增加到1860行,或者说每个实现155行。实际上如果你考虑到使用时可以互换SmallStringOpt和CowString的次序,那么有二十四个实现。但是,小字符串使用COW不是一个有效率的设计决策,所以我们总是在SmallStringOpt中使用CowString而不是相反。 总结 basic_string是一个非常复杂的组件。但是,仔细地采用基于策略的设计能够把你的生产率提高到最高。通过使用有限几个策略实现,你能够选择是直接的,还是小字符串优化的,还是引用记数的basic_string。这一切只需对模板类传入几个参数就可完成。 参考书目 [1] Herb Sutter. "Optimizations that Aren't (In a Multithreaded World)," C/C++ Users Journal, June 1999. [2] Kevlin Henney. "From Mechanism to Method: Distinctly Qualified," C/C++ Users Journal C++ Experts Forum, May 2001, http://www.cuj.com/experts/1905/henney.htm. [3] Andrei Alexandrescu. Modern C++ Design (Addison-Wesley, 2001). [4] Andrei Alexandrescu. "Traits on Steroids," C++ Report, June 2000, http://ftp.sj.univali.br/prof/Fernando%20Montenegro/artigos/GenericProgramingCPP02.htm.
|