垃圾回收站

June 24, 2007

Javaer 双修C++的key point

[ 分类: 其他技术 ] 由 弗里曼·潘 发表于 8:23 pm

    作者:江南白衣
    关键是把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,还是想说几句。
>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 中复杂的东西。前提是,你对你要用的东西有足够的认识--不仅能用,要知道它将干什么。

非典型秃子 评论于 2005-10-13 19:50  回复 更多评论

# re: Javaer 双修C++的key point

谢谢这么详细的批注
3. 我本来还想写一条,尽量用Refrence,少用指针。只是java下什么都是new的,还真要改一下习惯。Loki嘛,非标准的东西不是很想用,怕了。
4.Javaer对哪些是异常,哪些是错误代码已经分的很清,一般不会弄错:)
5.我有足够认识也没用阿,还要整个开发团队认识他,接手维护的人认识他,想想还是不要了:)
谢谢你的批注,我又改了下原文。

calvin 评论于 2005-10-14 10:50  回复 更多评论

# re: Javaer 双修C++的key point

你第五条 “更加尽量不用Template、STL、Boost 中复杂的东西” 和你前面的使用vector不是自相矛盾?
STL是标准C++的一部分已经7年了, 如果仍然要以”为了整个团队和日后的维护” 的原因而不去使用它, 那么这个团队最好转向Java方面去算了. 给那些愿意使用STL的C++程序员少一个枷锁和障碍吧.

ilovevc 评论于 2005-10-14 20:08  回复 更多评论

# re: Javaer 双修C++的key point

hehe,我是指STL中复杂的部分阿,vector 这么简单当然不算在内。
比如TypeList,traits,MPL, 一些写得很复杂的Template语法配合Boost中一些陌生的库,有看天书的感觉:(

江南白衣@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,确实,我没有大规模使用的经验。
但是从我的运用情况来看,smart pointer的使用大多在引用一些不具备clone语意的对象上面,例如数据库对象,套接字,其他具有资源性质的对象上。
另外,极少数情况下,smart pointer可以用来改善性能,而又不破坏程序结构。
对于不可copy的对象,很多时候可以通过refrence,而不是smart pointer,通常这都是可行的,而且,有助于遏制职责划分不清之类的错误发生。
不过,我的这种看法也许是错误的,大胆的尝试大规模使用smart pointer,也许会利大于弊,但是,在实践过之前,我无法确定会发生什么。
关于第五条,我有一些经验,也许有用。在C++设计过程中,通常,我们会在两个角色之间转换:生产程序员和客户程序员,我们需要保持两种角色之间衔接的简单性。例如,STL的实现,可以很复杂,但是,必须保持使用上的简单性,要足够简单。为了实现这种使用上的简单性,在STL的实现上合理运用高超的技巧,就是值得的--这种复杂性不会扩散。如果STL的内部实现简单了,但是代价是接口或者使用的时候的复杂,那么这种简单就是有问题的。
一种复杂性,导致了整体的简单性,就是有益的,反之,则是有害的。判断一种复杂性是不是可以采用,我的标准是:如果这种复杂性不会扩散,那么,可以大胆一点,如果会扩散,那么就需要谨慎。我想,这样比简单的回避复杂性更有效。
当然,复杂性是手段,不是目的,我这里并不是鼓励卖弄技巧和试验复杂方法,只是在简单方法不能完成任务时,不妨试一试所谓的复杂方法。

非典型秃子 评论于 2005-10-17 11:25  回复 更多评论

http://www.blogjava.net/calvin/archive/2005/10/10/15132.html


0 条评论 »

还没有人对这篇文章发表评论,赶紧留一个吧。

RSS feed for comments on this post. TrackBack URI

相关文章:
  • C# .NET interview questions
  • 桌面to-do-list的简单实现
  • Efficient and DYNAMIC Server-Side Paging with SQL Server 2000
  • 《财富》推荐的75本必读书
  • XPath 2.0, XQuery 1.0 和 XSLT 2.0函数
  • 魔兽四个种族的兵都在说什么?
  • 发表评论