David's profile好男人的空间PhotosBlogLists Tools Help

Blog


    September 23

    程序员对C++的需求变化

          In 1990, people wanted to know what C++ was. By 1992, they wanted to know how to make it work. Now C++ programmers ask higher-level questions: How can I design my software so it will adapt to future demands? How can I improve the efficiency of my code without compromising its correctness or making it harder to use? How can I implement sophisticated functionality not directly supported by the language?


    Cited from Scott Meyers' More Effective C++.
    September 20

    好男人的标准(二)

          要有控制自我的能力。想做一个成功男人,就要学会控制自己在各方面的一些不良习惯。比如有些人玩游戏成瘾,就是缺乏自控力的表现。须知"游戏中升了级,生活中的级别你怎么办。"有很多人在工作时间喜欢做自己的私人事情,这实际上也是缺乏自控力的表现。
          美国著名成功学大师"戴尔.卡耐基"先生曾说"我们每个人,每天都应该做两件自己不愿意做的事情",其实这就是一种培养自己自控力的好方法。大多数人每天都生活在一种思维定式里面,并且渴望这种生活延续下去。这种思维定式促成了很多不良习惯的养成。
          想做一个好男人,首先要学会控制自我。

    C++:灵巧指针的使用注意事项

         注意事项:不要同时既使用灵巧指针又使用原始指针(raw pointer)来指向同一个对象。示例代码如下:
    #include<iostream>
    #include<boost/shared_ptr.hpp>
    using namespace std;
    class A{
    private:
            boost::shared_ptr<int> x;
    public:
            A(){}
      //~A(){}
    };
    int main(){
     
     A * aa=new A;
     boost::shared_ptr<A> a(aa);
     delete aa;
     return 0;
    }
     
         上面一段代码看上去一点问题没有,它顺利通过了编译和链接过程,但是在运行时导致一个错误。因为我们同时使用A*和boost::shared_ptr<A>来指向了同一个对象,对于灵巧指针boost::shared_ptr<A>,它的引用计数值为1,在主函数退出之前将会析构它所指向的对象,而在这之前,我们已经通过delete aa析构过这个对象。这就是产生运行时错误的原因。
          把上面代码中的delete语句去掉,就不会产生这个问题,但是那样将导致代码的不协调,即new和delete数目不相等。正确的做法是使用RAII(Resource Acquisition Is Intialization)方法,即使用语句boost::shared_ptr<A> a(new A);
    在获取资源的同时对a做初始化。
    September 15

    《不得不爱》歌词

    天天都需要你爱
    我的心思由你猜
    i love you
    我就是要你让我每天都精彩
    天天把它挂嘴边
    到底什么是真爱
    i love you
    到底有几分说得比想像更快
    是我们感情丰富太慷慨
    还是要上天安排
    是我们本来就是那一半
    还是舍不得太乖
    是那一次约定了没有来
    让我哭得像小孩
    是我们急着证明我存在
    还是不爱会发呆
    baby
    不得不爱,不知快乐从何而来
    不得不爱,放下悲伤从何而来
    不得不爱,否则我就失去未来
    好象什么尤其不能自己很失败
    可是每天都过的精彩
    天天都需要你爱
    我的心只有你在
    i love you
    我就是要你让我每天都精彩
    天天把他挂嘴边
    到底什么是真爱
    i love you
    到底有几分说得比想像更快
    会不会有一点无奈
    会不会有一点太快
    可是你给我的爱
    让我养成了依赖
    心中充满爱的节拍
    天天都需要你爱
    我的心随有你在
    i love you
    我就是要你让我每天都精彩.
    September 14

    更换主页歌曲

         最近玩《劲舞团》,听到潘玮柏的《不得不爱》不错,把它设成主页歌曲。大家听听怎么样?
    September 11

    C++:模板元编程入门

        模板是C++语言的一个优良特性,模板元编程就是编写那些在程序编译的过程中运行的程序。英文为TMP(Template Metaprogramming)。TMP的一个入门程序是求阶乘的程序:
    #include<iostream>
    using namespace std;

    template<unsigned n>
    struct Factorial{
        enum{value=n*Factorial<n-1>::value};//enum hack
    };

    template<>  //template complete specialization
    struct Factorial<0>{
        enum{value=1};
    };

    int main(){
        std::cout<<Factorial<5>::value<<endl;
        std::cout<<Factorial<200>::value<<endl;
        return 1;
    }

           上面这个小程序是通过Factorial模板的递归实例化来完成在编译阶段对n阶乘的计算,比如在编译Factorial<5>时,编译器将会自动把它转化为5*4*3*2*1*Factorial<0>,从而将其替换为120;在编译Factorial<200>时将会产生溢出,会产生很多警告。如果不是采用模板元编程,那么编译器就不会产生这些警告,导致在运行时产生错误的结果。
           上面这个程序说明模板元编程的两点好处:(1)将运行时工作转化到编译时来完成,从而可以做到及早的发现和改正错误, 并使得程序的运行时间缩短;(2)减小程序所占用的空间。

    #
    September 10

    C++:函数重载的一个作用

         函数重载有一个作用是可以将运行时才能判断出来的事情转换成编译时就可以做。比如下面一个程序:
    template<typename IterT, typename DistT>
    void advance(IterT& iter, DistT d){
          if(typeid(typename std::iterator_traits<IterT>::iterator_category)==typeid(std::random_access_iterator_tag)){
                  //.................
          }
          else if(typeid(typename std::iterator_traits<IterT>::iterator_category)==typeid(std::bidirectional_iterator_tag)){
                  //.................
          }
          else if(typeid(typename std::iterator_traits<IterT>::iterator_category)==typeid(std::input_iterator_tag)){
                  //.................
          }
    }

        这个程序对于迭代器类型的判断是通过if...else...在运行时进行的,但是通过使用函数重载就可以使这种判断在编译阶段就可以完成。使用函数重载的代码如下:
    //先针对
    std::random_access_iterator_tag,std::bidirectional_iterator_tag,std::input_iterator_tag三种类型定
    //义三个重载函数

        template<typename IterT,typename DistT>
    void doAdvance(IterT& iter,DistT d,std::random_access_iterator_tag)
    {
        iter+=d;
    }

    template<typename IterT,typename DistT>
    void doAdvance(IterT& iter,DistT d,std::bidirectional_iterator_tag){
        if(d>=0){
            while(d--) ++iter;
        }

        else{
            while(d++) --iter;
        }
    }

    template<typename IterT,typename DistT>
    void doAdvance(IterT& iter,DistT d,std::input_iterator_tag){
        if(d<0){
            throw std::out_of_range("Negative distance");
        }
        while(d--) ++iter;
    }

    //然后将他们集成到一个统一的接口中
    template<typename IterT,typename DistT>
    void advance1(IterT& iter,DistT d){                       //将IterT类型的迭代器iter移动d个距离
        doAdvance(iter,d,typename std::iterator_traits<IterT>::iterator_category());
    }

    ####