• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
    • 軟件測試技術
    • 軟件測試博客
    • 軟件測試視頻
    • 開源軟件測試技術
    • 軟件測試論壇
    • 軟件測試沙龍
    • 軟件測試資料下載
    • 軟件測試雜志
    • 軟件測試人才招聘
      暫時沒有公告

    字號: | 推薦給好友 上一篇 | 下一篇

    Bjarne Stroustrup的FAQ:C++的風格與技巧

    發布: 2008-4-23 15:44 | 作者: 不詳 | 來源: www.wushuang.net | 查看: 121次 | 進入軟件測試論壇討論

    領測軟件測試網


    對于現在的大多數編譯器,中間變量p的初始化將會觸發一個易于了解的錯誤。這個竅門在很多語言中都是通用的,而且在所有的標準創建中都必須這樣做。在成品的代碼中,我也許可以這樣寫:

    template<class Container>
    void draw_all(Container& c)
    {
    typedef typename Container::value_type T;
    Can_copy<T,Shape*>(); // accept containers of only Shape*s

    for_each(c.begin(),c.end(),mem_fun(&Shape::draw));
    }

    這樣就很清楚了,我在建立一個斷言(assertion)。Can_copy模板可以這樣定義:

    template<class T1, class T2> struct Can_copy {
    static void constraints(T1 a, T2 b) { T2 c = a; b = a; }
    Can_copy() { void(*p)(T1,T2) = constraints; }
    };

    Can_copy(在運行時)檢查T1是否可以被賦值給T2。Can_copy<T,Shape*>檢查T是否是Shape*類型,或者是一個指向由Shape類公共繼承而來的類的對象的指針,或者是被用戶轉換到Shape*類型的某個類型。注意這個定義被精簡到了最。

    一行命名要檢查的約束,和要檢查的類型
    一行列出指定的要檢查的約束(constraints()函數)
    一行提供觸發檢查的方法(通過構造函數)

    注意這個定義有相當合理的性質:

    你可以表達一個約束,而不用聲明或復制變量,因此約束的編寫者可以用不著去設想變量如何被初始化,對象是否能夠被復制,被銷毀,以及諸如此類的事情。(當然,約束要檢查這些屬性的情況時例外。)
    使用現在的編譯器,不需要為約束產生代碼
    定義和使用約束,不需要使用宏
    當約束失敗時,編譯器會給出可接受的錯誤信息,包括“constraints”這個詞(給用戶一個線索),約束的名字,以及導致約束失敗的詳細錯誤(例如“無法用double*初始化Shape*”)。

    那么,在C++語言中,有沒有類似于Can_copy——或者更好——的東西呢?在《C++語言的設計和演變》中,對于在C++中實現這種通用約束的困難進行了分析。從那以來,出現了很多方法,來讓約束類變得更加容易編寫,同時仍然能觸發良好的錯誤信息。例如,我信任我在Can_copy中使用的函數指針的方式,它源自Alex Stepanov和Jeremy Siek。我并不認為Can_copy()已經可以標準化了——它需要更多的使用。同樣,在C++社區中,各種不同的約束方式被使用;到底是哪一種約束模板在廣泛的使用中被證明是最有效的,還沒有達成一致的意見。

    但是,這種方式非常普遍,比語言提供的專門用于約束檢查的機制更加普遍。無論如何,當我們編寫一個模板時,我們擁有了C++提供的最豐富的表達力量?纯催@個:

    template<class T, class B> struct Derived_from {
    static void constraints(T* p) { B* pb = p; }
    Derived_from() { void(*p)(T*) = constraints; }
    };

    template<class T1, class T2> struct Can_copy {
    static void constraints(T1 a, T2 b) { T2 c = a; b = a; }
    Can_copy() { void(*p)(T1,T2) = constraints; }
    };

    template<class T1, class T2 = T1> struct Can_compare {
    static void constraints(T1 a, T2 b) { a==b; a!=b; a<b; }
    Can_compare() { void(*p)(T1,T2) = constraints; }
    };

    template<class T1, class T2, class T3 = T1> struct Can_multiply {
    static void constraints(T1 a, T2 b, T3 c) { c = a*b; }
    Can_multiply() { void(*p)(T1,T2,T3) = constraints; }
    };

    struct B { };
    struct D : B { };
    struct DD : D { };
    struct X { };

    int main()
    {
    Derived_from<D,B>();
    Derived_from<DD,B>();
    Derived_from<X,B>();
    Derived_from<int,B>();
    Derived_from<X,int>();

    Can_compare<int,float>();
    Can_compare<X,B>();
    Can_multiply<int,float>();
    Can_multiply<int,float,double>();
    Can_multiply<B,X>();

    Can_copy<D*,B*>();
    Can_copy<D,B*>();
    Can_copy<int,B*>();
    }

    // 典型的“元素必須繼承自Mybase*”約束:

    template<class T> class Container : Derived_from<T,Mybase> {
    // ...
    };

    事實上,Derived_from并不檢查來源(derivation),而僅僅檢查轉換(conversion),不過這往往是一個更好的約束。為約束想一個好名字是很難的。

    既然已經有了優秀的qsort()函數,為什么還需要一個sort()?

    對于初學者來說,

    qsort(array,asize,sizeof(elem),elem_compare);

    看上去太古怪了,而且比這個更難理解:

    sort(vec.begin(),vec.end());

    對于專家來說,在元素與比較方式(comparison criteria)都相同的情況下,sort()比qsort()更快,這是很重要的。而且,qsort()是通用的,所以它可以用于不同容器類型、元素類型、比較方式的任意有意義的組合。舉例來說:

    struct Record {
    string name;
    // ...
    };

    延伸閱讀

    文章來源于領測軟件測試網 http://www.kjueaiud.com/


    關于領測軟件測試網 | 領測軟件測試網合作伙伴 | 廣告服務 | 投稿指南 | 聯系我們 | 網站地圖 | 友情鏈接
    版權所有(C) 2003-2010 TestAge(領測軟件測試網)|領測國際科技(北京)有限公司|軟件測試工程師培訓網 All Rights Reserved
    北京市海淀區中關村南大街9號北京理工科技大廈1402室 京ICP備2023014753號-2
    技術支持和業務聯系:info@testage.com.cn 電話:010-51297073

    軟件測試 | 領測國際ISTQBISTQB官網TMMiTMMi認證國際軟件測試工程師認證領測軟件測試網

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>