Javaer 双修C++的key point
作者:江南白衣
关键是把C++当作Java的sister,无关C事。
所以不要买〈C/C++…..〉为名的书,入门推荐〈Essential C++〉的中文版之类,开篇就讲C++/STL。
如果不幸学校里已经学了C,想办法忘掉它。
1. 用STL的 string ,不用char* 和strcpy()
辅以Boost的Tokenizer实现Java的Tokenizer
conversion/lexcial_cast实现字符串<->数值转换。
Regex实现正则表达式。
#include
#include
void main()
{
string str=”haha,hehe”;
tokenizer<> tok(str);
for(tokenizer<>::iterator beg=tok.begin(); beg!=tok.end();++beg)
{
cout << *beg << endl;
}
int i = lexical_cast<int>(”123″);
string s = lexical_cast<string>(123);
}
需要调用C API时,const char* cs = str.c_str() 转换。
2. 用STL的vector,不用 C式的array
vector在STL容器里也是首选的容器。
如果需要批量给vector赋初始值时,使用Boost的Assign.
如果容器内需要装载多种数据类型,使用Boost的Any.
#include <boost/any.hpp>
#include <boost/assign.hpp>
void main()
{
vector<any> vec;
vec+=1,”hello”;
}
需要调用C API时,&vec[0] 指向第一个元素
3.用Boost 的smart pointer,尽量少用普通指针
统一使用Boost的shared_ptr,解决诸如两个对象同时拥有第3个对象,异常处理和忘记delete的问题。当然,如果refrence可用的时候,就连指针都不要用了,可怜java下用惯了new。
shared_ptr<string> p2 ( new string(”Use shared_ptr ”));
4.使用STL 异常机制,不用C式的Return Error Code 机制
抛出标准的exception ,不要抛int,string等,一如Java。
何时用返回值,何时用Excetpion的判断,亦一如Java。
try
{
throw exception(”error”);
}
catch (exception e)
{
cout<<e.what()<<endl;
}
5. Keep it simple
不使用C式的特性如#define。
尽量不要运算符重载。
为了整个团队和日后的维护,更加尽量不用Template、STL、Boost 中复杂陌生的东西,如type traits, Typelist, mpl,lambda,bind….
STL 似乎是个分水岭,从此C++ 不断的向学院派,复杂化发展–TR1、TR2到0x。而Java,C#们则始终保留基本语言的特征,通过不断的制定更多实用的类库、规范,抢占越来越多的市场。
6. 必备读物
2006年入行的C++程序员是幸福的,因为又多了两本实用读物的中文版,〈C++必知必会C++ Common Knowledge )〉和两位老怪返璞归真之作〈C++ Coding Standard〉,两本都是2005年新鲜写好的书,可以用来淘汰掉上一代的一大堆所谓必备书籍。
7. 益智读物
某人说过,决定学一门新语言,需其能给自己的思维模式带来冲击。
所以,推荐下面三本能带来冲击的益智读物:
〈Modern C++ Design - Generic Programming and Design Patterns 〉
〈C++ Templates - The Complete Guide〉
〈C++ Template Metaprogramming Concepts,Tools and Techniques from Boost and Beyond 〉
上面的书虽然不赞成其复杂性而限制在大团队中运用,但对个人智力来讲就大有裨益,比那些在语言规范、编译器下绕来绕去的Effective系列Exceptional系列有趣得多。
发表于 2005-10-10 12:54 江南白衣 阅读(6106) 评论(8) 编辑 收藏 引用 所属分类: 全部文档
评论
# re: Javaer 双修C++的key point
更新了一下实际代码和书籍推荐。
calvin 评论于 2005-10-13 15:24 回复 更多评论
# re: Javaer 双修C++的key point
说的很好。不过作为一个cpper,还是想说几句。 非典型秃子 评论于 2005-10-13 19:50 回复 更多评论
# re: Javaer 双修C++的key point
谢谢这么详细的批注 calvin 评论于 2005-10-14 10:50 回复 更多评论
# re: Javaer 双修C++的key point
你第五条 “更加尽量不用Template、STL、Boost 中复杂的东西” 和你前面的使用vector不是自相矛盾? ilovevc 评论于 2005-10-14 20:08 回复 更多评论
# re: Javaer 双修C++的key point
hehe,我是指STL中复杂的部分阿,vector 这么简单当然不算在内。 江南白衣@ITO 评论于 2005-10-15 00:09 回复 更多评论
# re: Javaer 双修C++的key point
STL中基本上没有太复杂的部分了. 那是C++社区还没有这么”聪明”.
ilovevc 评论于 2005-10-16 09:58 回复 更多评论
# re: Javaer 双修C++的key point
不错,受益!
gaowei 评论于 2005-10-16 20:05 回复 更多评论
# re: Javaer 双修C++的key point
关于smart pointer,确实,我没有大规模使用的经验。 非典型秃子 评论于 2005-10-17 11:25 回复 更多评论
http://www.blogjava.net/calvin/archive/2005/10/10/15132.html
>3.用Boost 的smart pointer,尽量少用普通指针
少用指针是对的,但是广泛的使用smart pointer,会带来一些问题,第一,用了它们,意味着你可能过度的在new。第二,smart pointer的效率是比较差的。第三,潜在的循环引用风险,从而导致内存泄漏。
第二条,建议可以使用Loki::smart_ptr,效率差别很大。不过,boost1.33在这方面也开始作了些努力。
>4.使用STL 异常机制,不用Return Code 机制
千万不要!异常只用来处理真正的意外,而不应该用来处理错误。例如,创建一个文件,可能会失败,这时候一般应该返回错误而不是异常。但是,你的创加日志函数中创建文件失败,却适合抛出异常--假设日志是必须的。
>5. Keep it simple
保持简单,尽可能的简单,但不要过于简单。这不仅仅适合爱因斯坦的物理学,也适合软件。
你尽可以用C++中的Template、STL、Boost 中复杂的东西。前提是,你对你要用的东西有足够的认识--不仅能用,要知道它将干什么。
3. 我本来还想写一条,尽量用Refrence,少用指针。只是java下什么都是new的,还真要改一下习惯。Loki嘛,非标准的东西不是很想用,怕了。
4.Javaer对哪些是异常,哪些是错误代码已经分的很清,一般不会弄错:)
5.我有足够认识也没用阿,还要整个开发团队认识他,接手维护的人认识他,想想还是不要了:)
谢谢你的批注,我又改了下原文。
STL是标准C++的一部分已经7年了, 如果仍然要以”为了整个团队和日后的维护” 的原因而不去使用它, 那么这个团队最好转向Java方面去算了. 给那些愿意使用STL的C++程序员少一个枷锁和障碍吧.
比如TypeList,traits,MPL, 一些写得很复杂的Template语法配合Boost中一些陌生的库,有看天书的感觉:(
但是从我的运用情况来看,smart pointer的使用大多在引用一些不具备clone语意的对象上面,例如数据库对象,套接字,其他具有资源性质的对象上。
另外,极少数情况下,smart pointer可以用来改善性能,而又不破坏程序结构。
对于不可copy的对象,很多时候可以通过refrence,而不是smart pointer,通常这都是可行的,而且,有助于遏制职责划分不清之类的错误发生。
不过,我的这种看法也许是错误的,大胆的尝试大规模使用smart pointer,也许会利大于弊,但是,在实践过之前,我无法确定会发生什么。
关于第五条,我有一些经验,也许有用。在C++设计过程中,通常,我们会在两个角色之间转换:生产程序员和客户程序员,我们需要保持两种角色之间衔接的简单性。例如,STL的实现,可以很复杂,但是,必须保持使用上的简单性,要足够简单。为了实现这种使用上的简单性,在STL的实现上合理运用高超的技巧,就是值得的--这种复杂性不会扩散。如果STL的内部实现简单了,但是代价是接口或者使用的时候的复杂,那么这种简单就是有问题的。
一种复杂性,导致了整体的简单性,就是有益的,反之,则是有害的。判断一种复杂性是不是可以采用,我的标准是:如果这种复杂性不会扩散,那么,可以大胆一点,如果会扩散,那么就需要谨慎。我想,这样比简单的回避复杂性更有效。
当然,复杂性是手段,不是目的,我这里并不是鼓励卖弄技巧和试验复杂方法,只是在简单方法不能完成任务时,不妨试一试所谓的复杂方法。
)告知,即刻删除。