• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            BillyYu

            Why C++? ( Both versions)---轉(zhuǎn)載自CSDN

            劉未鵬(pongba) /文

            waterwalk /譯

            C++的羅浮宮(http://blog.csdn.net/pongba)

            首先非常感謝waterwalk的辛勤翻譯:-) waterwalk把翻譯回貼在原文的下面了,為
            了方便閱讀我提取出來編輯以后重發(fā)一個(gè)帖子。這篇文章原本是想對(duì)最近C/C++爭論
            系統(tǒng)的整理一下一些思考的,但由于一開始的時(shí)候用英文寫了兩段,后來就干脆都用
            英文了,造成很多人閱讀的麻煩,在此抱歉。不過好在waterwalk翻譯了整篇文章,
            于是單獨(dú)貼在這里:-)

            問題

            為什么用C++呢? 在你皺著眉頭離開之前,試著回答這個(gè)簡單的問題。效率,是么
            ?人人都知道這個(gè)。但情況是,當(dāng)一個(gè)人開始討論編程語言或與其相關(guān)的話題時(shí),他
            必須要非常明確而有針對(duì)性。為什么呢?我來問你另一個(gè)問題:如果效率是人們使用
            C++的唯一理由,那么為啥不直接用C呢?C被認(rèn)為比C++效率更高(嗯嗯,我知道C沒
            有比C++的效率高多少,所以這里別誤解我的意思,因?yàn)榧词顾鼈兌咝氏嗤瑒?br>才的問題依然存在)。

            迷思

            我知道你又要說“更好的抽象機(jī)制”了,因?yàn)楫吘笴++是要設(shè)計(jì)成一個(gè)更好的C的。
            C++沒有犧牲效率,同時(shí)又添加了這么多高級(jí)特性。但問題是,“開發(fā)者們真的需要
            這些高級(jí)特性么?”。畢竟我們一直聽人講KISS之類的東西。我們也都聽到有聲稱C
            比C++更KISS所以我們要用C云云。這種持續(xù)不斷的爭論將C與C++之間的比較變成了一
            個(gè)大大的迷題(或者說是混亂)。令人驚訝的是,貌似的確有很多人更加傾向于用C
            ,最大的理由就是C++實(shí)在是太難用對(duì)了。甚至Linus也這么想。

            這種現(xiàn)象最大的影響就是當(dāng)人們?cè)贑和C++之間權(quán)衡時(shí),使人們傾向于使用C。而且
            一旦人們開始用C,他們很快就適應(yīng)并滿足了(其實(shí),在任何語言乃至任何人類活動(dòng)
            中都有此現(xiàn)象,C++亦然,比如常常聽到有人說“XX語言我用了這么多年,一直用得
            好好的”,照這種說法任何圖靈完備的語言還不都是能用來編程?)。于是即使他們
            還沒有試試C++,或者他們還沒成為好的C++程序員時(shí),他們就開始聲稱C比C++更好了
            。然而其實(shí)呢,真實(shí)的答案往往總是取決于實(shí)際情況的。

            我說過“取決于實(shí)際情況”了么?那到底實(shí)際情況是什么呢?顯然,有些領(lǐng)域C是
            更好的選擇。例如設(shè)備驅(qū)動(dòng)開發(fā)就不需要那些OOP/GP技巧。而只是簡單的處理數(shù)據(jù),
            真正重要的是程序員確切地知道系統(tǒng)是如何運(yùn)轉(zhuǎn)的,以及他們正在做什么。那么寫操
            作系統(tǒng)呢?我本人并沒有參與任何操作系統(tǒng)的開發(fā),但我讀過不少操作系統(tǒng)代碼(大
            多是unix的)。我的感覺是操作系統(tǒng)很大一部分也不需要OOP/GP。

            但是,這就表示在所有效率重要的領(lǐng)域,C都是比C++更好的選擇么?未必。

            答案

            讓我們一個(gè)一個(gè)來分析。

            首先,當(dāng)人們關(guān)注效率時(shí),有2種效率——時(shí)間效率(例如OS,運(yùn)行時(shí)庫,實(shí)時(shí)應(yīng)
            用程序,high-demanding的系統(tǒng))和空間效率(例如各種嵌入式系統(tǒng))。但是,這樣
            的分類并不能幫我們決定用C還是C++,因?yàn)镃和C++的時(shí)空效率都很高。真正影響選擇
            語言的因素是業(yè)務(wù)邏輯(這里的“業(yè)務(wù)邏輯”并非表示“企業(yè)應(yīng)用業(yè)務(wù)”)。例如,
            使用OOP/GP來表達(dá)邏輯(或者說代碼的結(jié)構(gòu))好呢,還是就只用數(shù)據(jù)和過程好呢?

            據(jù)此觀點(diǎn),我們可以把應(yīng)用程序大致分為兩類(當(dāng)然前提是關(guān)注的是C/C++而不是
            java/C#/ruby/erlang等等):底層應(yīng)用程序和高層應(yīng)用程序。這里底層是指像OB/
            OO和GP沒啥用處的地方, 其余歸到高層。顯然,在所有C/C++應(yīng)用的領(lǐng)域(這些領(lǐng)
            域需要C/C++的效率),屬于高層的應(yīng)用有很多(可以看看Bjarne Stroustrup在他主
            頁上的列表)。在這些領(lǐng)域中,抽象至少是和效率一樣重要的。而這些正是C++適用
            的場合。

            等等還有。即使在程序員不需要高級(jí)抽象的領(lǐng)域,也不是就絕對(duì)用不到C++的。為
            啥呢?僅僅是因?yàn)槟愕拇a中沒有用類或模板并不意味著不能用以類或模板實(shí)現(xiàn)的庫
            。因?yàn)橛腥绱吮姸喾奖愕腃++庫(還有即將到來的tr1/tr2),我覺得有充分的理由在
            這些領(lǐng)域中使用C++——你可以在編碼時(shí)僅使用C++中的C核心(以任何你喜歡的方式
            來KISS),同時(shí)還能用強(qiáng)大的C++庫(比如STL容器、算法和tr1/tr2的組件)。

            最后,我認(rèn)為人們還常常忽略了一點(diǎn)——有時(shí)KISS也是建立在抽象上的。我覺得M
            atthew Wilson在他新書《Extended STL,卷1》的序言中對(duì)此做了很好的闡釋。他
            寫了2段代碼,一段用C,另一段用C++:

             

            // in C

            DIR
            *  dir = opendir(".");

            if(NULL != dir)

            {

              struct dirent
            *  de;

              
            for(; NULL != (de = readdir(dir)); )

              {

                struct stat st;

                
            if0 == stat(de->d_name, &st) &&

                    S_IFREG 
            == (st.st_mode & S_IFMT))

                {

                  remove(de
            ->d_name);

                }

              }

              closedir(dir);

            }



            // in C++

            readdir_sequence entries(
            ".", readdir_sequence::files);



            std::for_each(entries.begin(), entries.end(), ::remove);

             

            而在C++09里面更簡單:

            // in C++09

            std::for_each(readdir_sequence(
            ".", readdir_sequence::files), ::remove)
            ;


            也就是說,我認(rèn)為即使一個(gè)人在自己的代碼里不需要類或模版,他也有理由用C++
            ,因?yàn)樗玫哪切┓奖愕腃++庫用到了類和模板。如果一個(gè)高效的容器(或智能指針
            )能把你從無聊的手動(dòng)內(nèi)存管理中解放出來,為啥還要用那原始的malloc/free呢?
            如果一個(gè)更好的string類(我可沒說std::string,地球人都知道那個(gè)不是C++中能做
            出的最好的string類)或正則表達(dá)式類能把你從一坨一坨的、你看都不想看的處理字
            符串的代碼中解脫出來,那么為啥還要手動(dòng)去做這些事呢?如果一個(gè) "transform"(
            或"for_each")能夠用一行代碼把事情漂亮搞定,為啥還要手寫一個(gè)for循環(huán)呢?如
            果高階函數(shù)能滿足你的需要,那么為啥還要用笨拙的替代方法呢?(OK,我知道,最
            后兩個(gè)需要C++加入lambda支持才真正擺脫雞肋的罵名——這正是C++0x的任務(wù)嘛)

             總之,我認(rèn)為KISS并不等同于“原始”;KISS意味著用最適合的工具來做事情,這
            里“最合適”的意思是工具能夠幫你以盡量直接簡潔的方式來表達(dá)思想,同時(shí)又不降
            低代碼的可讀性,另外還保持代碼容易理解。

             真正的問題

            人們可能會(huì)說,相較于被正確使用而言,C++(遠(yuǎn)遠(yuǎn))更容易被錯(cuò)誤使用。而相比
            而言,C程序的復(fù)雜性更容易管理和控制。在C++中,一個(gè)普通程序員很可能會(huì)寫出一
            堆高度耦合的類,很快情況就變得一團(tuán)糟。但這個(gè)其實(shí)是另外一個(gè)問題。在另一方面
            ,這種事情也很可能發(fā)生在任何一門面向?qū)ο笳Z言中,因?yàn)榭偸怯谐绦騿T在還沒弄懂
            什么是HAS-A和IS-A之前,就敢于在類上再寫類,疊床架屋的一層一層摞上去。他們
            學(xué)會(huì)了在一門特定的語言中如何定義類,如何繼承類的語法,然后他們就認(rèn)為自己已
            經(jīng)掌握了OOP的精髓了。另一方面,這一問題在C++中更為嚴(yán)重,因?yàn)镃++有如此眾多
            的偶然復(fù)雜性在阻礙設(shè)計(jì);而且C++又是如此靈活,很多問題在C++中都有好幾種解決
            辦法(想想那么多的GUI庫吧),于是在這些選擇中進(jìn)行權(quán)衡本身就成了一個(gè)困難。
            C++中的非本質(zhì)復(fù)雜性是其歷史包袱使然,而C++0x正是要努力消除這些非本質(zhì)復(fù)雜
            性(在這方面C++0x的工作的確做得很不錯(cuò))。對(duì)于設(shè)計(jì)來說,靈活性不是個(gè)壞事情
            ——可以幫助好的設(shè)計(jì)者作出好的設(shè)計(jì)。如果有人抱怨說這個(gè)太費(fèi)腦細(xì)胞了,那可能
            是這個(gè)設(shè)計(jì)者本身的問題,而不能怪語言。可能就不該讓他來作設(shè)計(jì)。如果你擔(dān)心C
            ++的高級(jí)特性會(huì)把你的同事引入歧途,把項(xiàng)目搞砸,那你也許應(yīng)該制定一份編碼標(biāo)
            準(zhǔn)并嚴(yán)格推行(或者你也可以遵循C++社群這些年積攢下來的智慧,或者在必要時(shí),
            只使用C++中的C或C with class那部分),而不是因?yàn)橛酗L(fēng)險(xiǎn)就躲開C++(其實(shí)這些
            風(fēng)險(xiǎn)可以通過一些政策來避免的),因?yàn)槟菢拥脑挘憔蜎]法用那些C++的庫了。

             另一方面,其實(shí)一個(gè)更為重要的問題是一個(gè)心理學(xué)問題——如果一門語言中存在某
            個(gè)奇異的特性或旮旯,那么遲早總會(huì)有人發(fā)現(xiàn)的,總會(huì)有人為之吸引的,然后就使人
            們從真正有用的事情中分心出來(這有點(diǎn)像Murphy法則),更不用說那些有可能對(duì)真
            正問題帶來(在某種程度上)漂亮的解決方案的語言旮旯了。人們本性上就容易受到
            稀有資源的誘惑。奇技淫巧是稀有資源,于是奇技淫巧便容易吸引人們的注意力,更
            別說掌握一個(gè)技巧還能夠讓那人在他那圈子里感覺非常牛了。退一萬步,你會(huì)發(fā)現(xiàn),
            即使是一個(gè)廢柴技巧也能引起人們足夠的興趣來。

             C++中有多少陰暗角落呢?C++中又有多少技巧呢?總的來說,C++中,有多少非本
            質(zhì)復(fù)雜性呢?(懂一定C++的人一定知道我在說什么)

             平心而論,近年來(現(xiàn)代C++中)發(fā)現(xiàn)的大多數(shù)技巧或(如果你愿意稱之為)技術(shù)
            實(shí)際上都是由實(shí)際需求驅(qū)動(dòng)的,尤其是需要實(shí)現(xiàn)高度靈活而又普遍適用(generic)
            的類庫 (例如boost中的那些玩意)。而這些技巧也的確(在某種程度上)提供了對(duì)
            實(shí)際問題的漂亮解決方案。讓我們來這么想一下,如果你處于一個(gè)兩難境地:要么用
            那些奇技淫巧來做點(diǎn)很有用的東西,要么不做這樣其他人也就沒得用。你會(huì)如何選擇
            呢?我知道boost的英雄們選擇了前者——不管多么困難多么變態(tài)多么齷齪,把它做
            出來!

             但所有這些爭論都不能改變一個(gè)事實(shí):我們理應(yīng)享有一個(gè)語言,能夠讓我們用代碼
            清晰的表達(dá)思想。以boost.function/boost.bind/boost.tuple為例,variadic tem
            plates可以大大簡化這幾個(gè)庫的實(shí)現(xiàn)(減至幾乎是原先1/10的代碼行數(shù)),同時(shí)代
            碼也(遠(yuǎn)遠(yuǎn))更加簡潔易懂。Auto,initializer-list,rvalue-reference,templ
            ate-aliasing,strong-typed enums,delegating-constructors,constexpr,al
            ignments,inheriting-constructors,等等等等,所有這些C++0x的特性,都有一
            個(gè)共同目的——消除語言中多方面的非本質(zhì)復(fù)雜性或語言中的尷尬之處。

             正如Bjarne Stroustrup所說,很顯然C++太過復(fù)雜了,很顯然人們被嚇壞了,并且
            時(shí)不時(shí)就不用C++了。但“人們需要相對(duì)復(fù)雜的語言去解決絕對(duì)復(fù)雜的問 題”。我們
            不能通過減少語言特性而使其更加強(qiáng)大。復(fù)雜的特性就連模板甚至多繼承這樣的也是
            有用的——如果你正好需要它們,而且如果你極其小心使用,不要搬起石頭砸自己的
            腳的話。其實(shí)在所有C++的復(fù)雜性當(dāng)中,真正阻礙了我們的是“非本質(zhì)復(fù)雜性”(有
            人稱之為“尷尬之處”),而不是語言所支持的編程范式(其實(shí)也就3個(gè)而已)。而
            這也正是我們應(yīng)該擁抱C++0x的重要原因,因?yàn)镃++0x正是要消除那些長期存在的非本
            質(zhì)復(fù)雜性,同時(shí)也使得那些奇技淫巧不再必要(很顯然,目前這些技巧堆積如山,翻
            翻那些個(gè)C++的書籍,或者瞅瞅boost庫,你就知道我在說啥了),這樣我們就能夠直
            觀清晰的表達(dá)思想。

             結(jié)論

            C++難用,更難用對(duì)。所以當(dāng)你決定用它時(shí),要小心,要時(shí)刻牢記自己的需求,所
            要達(dá)到的目的。這里有一個(gè)簡單的指南:

             我們需要高效率么?

             如果需要,那么我們需要抽象么(請(qǐng)仔細(xì)思考這一點(diǎn),因?yàn)楹茈y評(píng)估使用C++高級(jí)特性是否能夠抵
            消誤用這些機(jī)制的風(fēng)險(xiǎn);正確的回答取決于程序員的水平有多高,遵循哪種編碼標(biāo)準(zhǔn)
            以及編碼標(biāo)準(zhǔn)執(zhí)行得如何,等等)?

             如果是,那么用C++吧。如果不是,那么,

             我們需要用C++庫來簡化開發(fā)么?

             如果是,那就用C++吧。但同時(shí)必須時(shí)刻牢記你在做什么——如果你的代碼不需要
            那些“漂亮的”抽象,那就別試圖使用以免陷入其中。別只是因?yàn)槟阍?cpp文件中寫
            代碼以及你用的是C++編譯器就要用類啊、模板啊這些東西。

             如果不是,那就用C,不過你又會(huì)想為啥不僅僅使用C++中屬于C的那部分核心呢?
            還是老原因:人們很容易就陷入到語言的“漂亮”特性中去了,即使他們還不知道這
            些特性是否有用。我都記不清有多少次自己寫了一大堆的類和繼承,到最后反倒要問
            自己“要這么些個(gè)類和繼承做什么呀?”。所以,如果你能堅(jiān)持只用C++中C或C wit
            h class的那部分,并遵循“讓簡單的事情保持簡單”的理念;或者你需要把C代碼
            遷移到C++中來的話,那么就用C++吧,但要十分小心。另一方面,如果你既不需要抽
            象機(jī)制,也不需要C++庫,因?yàn)槭虑榉浅:唵危恍枰奖愕慕M件例如容器和字符串
            ,或者你已認(rèn)定C++能夠給項(xiàng)目帶來的好處微乎其微,不值得為之冒風(fēng)險(xiǎn),或者干脆
            就沒那么多人能用好C++,那么可能你還是只用C的好。

             底線是:讓簡單的事情保持簡單(但同時(shí)也請(qǐng)記住:簡單性可以通過使用高級(jí)庫來
            獲得);必要時(shí)才使用抽象(切記不可濫用;遵循好的設(shè)計(jì)方法和最佳實(shí)踐)。

            原文:
            The Problem

            So, why C++? Before you frown and turn away. Just try to answer this simple question.

            Efficiency, right? Everybody knows the answer. But as it turned out, when discussing a programming language or everything related to one, one should be very specific. Now why’s that? Let me ask you another question: if efficiency is the only reason people use C++, then why don’t they just use C? C is admittedly more efficient than C++ (yeah, yeah, I know it has been proved that C isn’t to any significant extent more efficient than C++, so don’t get me wrong here, because even if they are equally efficient, the problem still exists).

            The Myth

            I know you are going to say “better abstraction mechanism”, because after all C++ is designed to be a better C, one that has uncompromised efficiency and yet at the same time has all those fancy high-level features. But then the problem comes down to “does it really matter if the developers need those fancy features?”  I mean, after all we all have been hearing voices about KISS and stuff, and we all have heard about the claim that, compared to C++, C is more KISS so we should use C. This unstoppable argument has turned the comparison between C and C++ into a big myth (or maybe a mess). And surprisingly, it seems that many people do incline to C, the reason mostly being that C++ is so hard to use right. Even Linus thinks so, too.

            The real serious impact of this phenomenon is that it drives more people to C when they’re weighing their options, be them C and C++; and once they start using C, they will soon get satisfied and comfortable with what suffices, experiencing what is called “satisfaction”. This is when they will come out and claim that C actually is a better choice than C++ even though they didn’t actually try to use C++ or they aren’t adequately good C++ programmers at all. The real answer, however, almost always begins with “it depends”.

            So, did I say “it depends”? On what? Obviously there’re some areas where C is a better choice than C++. For instance, device driver development is usually something that doesn’t need fancy OOP/GP techniques. It’s just simple data manipulation; what really matters is the programmers know exactly how the system works, and what they’re doing. Now what about OS development? I’m not a guy who’s been involved in any kind of OS development myself, but having read a fair amount of OS code (Unix mostly), I’ve come to feel that there’s a significant part of the OS development that doesn’t need OOP/GP either.


            However, does that mean that, in all those areas where efficiency matters, C is a better choice than C++? Not really.

            The Answer

            Let’s do this case by case.

            First of all, when people are concerned about efficiency, there’re really two kinds of efficiency – time efficiency (e.g. OS, runtime, real-time applications, high-demanding systems) and space efficiency (e.g. all sorts of embedded systems). However, this categorization doesn’t really help us determine whether we should use C or C++, because C and C++ are both extremely efficient as to both time and space. What really affects our language choice (between C and C++, of course) is the business logic (here by “business”, I don’t mean the “enterprise application business”). For example, is it better to use OOP/GP to express the logic or is it better off being kept pretty much just about data and procedures.

            From this point of view, we can vaguely divide applications into two categories (of course, with the premise that what we’re concerned with is C/C++, not java/c#/ruby/erlang etc.): low-level applications and high-level applications, where low-level applications means the ones where fancy abstractions such as OB/OOP and GP are pretty much of no use, and high-level means all the rest. Now, obviously, of all the areas where C/C++ is used (because of their high-efficiency), there’re a significant number of “high-level” applications (see those listed on Bjarne Stroustrup’s homepage), where abstraction is just as important as, if not more important than efficiency. And those are precisely the places where C++ is used and useful in a unique sense, and where C++ is a better choice than C.

            Wait, there’s more. As it turns out, even in those areas where programmers don’t use high-level abstractions in their code per se, there might be a reason they should use C++, too. Why’s that? Just because your code don’t use class or templates doesn’t mean it doesn’t use a library that does. Considering the availability of all the handy C++ library facilities (with tr1/tr2 coming soon), I think there’s a pretty strong reason to use C++ in these cases - you can stick to the C core of C++ when coding (KISS in any way you want), and at the same time you’ve got some awesome C++ libraries at your disposal (e.g. STL containers and algorithms, tr1/tr2 components, etc.). And finally, there’s this one thing that’s always ignored by many people – sometimes KISS relies on abstractions. I think Matthew Wilson made a crystal clear point about this in the prologue of his new book “Extended STL, Vol 1”, where he laid down two blocks of code, one written in C and one in C++:

             

            // in C

            DIR
            *  dir = opendir(".");

            if(NULL != dir)

            {

              struct dirent
            *  de;

              
            for(; NULL != (de = readdir(dir)); )

              {

                struct stat st;

                
            if0 == stat(de->d_name, &st) &&

                    S_IFREG 
            == (st.st_mode & S_IFMT))

                {

                  remove(de
            ->d_name);

                }

              }

              closedir(dir);

            }

            // in C++

            readdir_sequence entries(
            ".", readdir_sequence::files);

            std::for_each(entries.begin(), entries.end(), ::remove);

            And it’s even simpler in C++09:

            // in C++09

            std::for_each(readdir_sequence(
            ".", readdir_sequence::files), ::remove);

            I think this is exactly the reason why one should use C++ even in those cases where he doesn’t really need class or templates in his own code – the handy C++ libraries he will find very useful does. Similarly, if an efficient container (or a smart pointer) will save you from all the boring job of manual manipulation of memory, then what’s the point of using the primitive malloc/free? If a better string class (I’m not talking about std::string; everybody knows it’s not the best C++ can do) or regex class  can relieve you of all the cluttered string-manipulation code you don’t even want to look at, then what’s the point of doing it manually. If a ‘transform’ (or a ‘for_each’) can do your job in one line so succinctly and clearly (and I know, of course, C++ need lambda function support for those – that’s what C++0x is for), then what’s the point of hand-written for-loops? If high-order function is really what you need, then what’s the point of using awkward workarounds to approach the same deal?

            KISS doesn’t mean “primitive”; KISS means using the most suitable tool for your job, where “most suitable” means the tool you use should help you express your mind as straight (and succinct) as possible, as long as it doesn’t compromise the readability and understandability of the code.

            The Real Problem

            People might say that C++ is much more easily misused than properly-used, and C, on the other hand, is always more manageable and controllable as to complexity. In C++, an average programmer might come up with a whole bunch of highly coupled classes that degenerates fast into a big mess. But this is actually a separate issue. On the one hand, it can pretty much occur in any object oriented language. There’re always programmers who dare to write classes on top of classes even before they have any idea what HAS-A is and what IS-A is; they learn all the syntax of defining a class and inheriting one from another and they thought they’ve grasped the essence of OOP. On the other hand, the reason it appears to be more serious in C++ is because C++ has so many accidental complexities that impede the design, and because C++ is so flexible that pretty much every problem in C++ has several alternative solutions (thinking of all the GUI libraries) so that weighing all the options becomes a hard job itself. The accidental complexities are a historical baggage that C++0x is trying so hard to (and hopefully will) get rid of; the flexibility with respect to design isn’t actually a bad thing if you think about it - it helps good designers make good designs; and if someone blame them for hurting his brain then maybe it’s his problem, not the language’s; maybe he shouldn’t be the one to make a design. And if you’re so worried that your fellow C++ coders will be enticed by fancy high-level features and that your project will eventually get screwed, then maybe what you should do is setting up a coding standard and enforce it (or you can just follow the collective wisdom, or stick to the C core or C with class part of C++ if necessary), not flinching away just because there’re risks (risks that can be avoided by policies), because then you will not be able to access all the C++ libraries anymore, mind you.

            On the other hand, there’s this more important psychological problem – if there’s a bizarreness in a language, then eventually someone will find it and people will be attracted by it, and it will draw energy from the main people effort of doing something really useful (It’s kind of like the Murphy's Law), let alone the ones that can lead to an (on some level) elegant solution to a real problem. People are inherently attracted by scarce resources. Corollary: Tricks and bizarrenesses are scarce resources, so they draw people’s attention, not to mention the fact that mastering a trick makes one feel special in the herd. The bottom line is, even useless tricks draw people’s attention so heavily.

            How many black corners are there in C++? How many tricks are there in C++? All in all, how many accidental complexities are there in C++?

            To be fair, most of the tricks and (you might say) techniques that have been discovered in recent years (i.e. modern C++) are driven by real needs, particularly the needs to implement highly flexible and generic library components (thinking of all the components in boost). And they did lead to (on some level) elegant solutions to real problems. Think about it this way: if you’re put in a place where either you have to use tricks to implement something really useful or you don’t implement it so other people won’t have the benefit of using it. What would you choose? I know that the boost heroes chose the former – implementing them, no matter how hard and tricky and cumbersome the implementation is.

            But all those arguments don’t change the fact that we deserve to have a language that supports a clean way to express our minds in code. Take boost.function/boost.bind/boost.tuple for examples, variadic templates will tremendously simplify (by reducing the LOC to nearly 1/10 of the original) the implementation of the three (and many, many more to come) libraries, and the code will become succinct and as simple as possible, too. Auto, initializer-list, rvalue-reference, template-aliasing, strong-typed enums, delegating-constructors, constexpr, alignments, inheriting-constructors, etc; all those C++0x features, they all have one goal – eliminating the various accidental complexities or embarrassments of the language.

            As Bjarne Stroustrup said, obviously C++ is too complicated; obviously people get scared and sometimes turn away. But “people need relatively complex language to deal with absolutely complex problems”. We can’t make a language more powerful by taking features away from it. Complex features like templates and even multiple-inheritance can be useful if they’re exactly what you need, you just have to use them very carefully and by necessity so that you don’t shoot yourself in the foot. Of all the complexities in C++, the ones that really get in our way are the accidental complexities (someone might call them “embarrassments”), not the paradigms the language supports (there’re only three). And that’s a very important reason why we should embrace C++0x, because it aims at eliminating the long standing accidental complexities C++ had and make obsolete all the arcane tricks (there’s absolutely huge amount of them out there; check all the C++ books and maybe the boost library and you’ll know what I’m talking about) so that we can express our mind clearly and directly.

             
            The Conclusion
            C++ is hard, and even harder to use correctly. So when you decide to use it, be careful, always know where you are and what you really want. Here’s a simple guideline:

            Do we need to be efficient?

            If so, then

            Do we need abstractions in our code (think very carefully on this one, because it’s very hard to estimate whether the benefit of using the high-level features of C++ outweighs the risk of using them incorrectly; the proper answer depends on how well trained your programmers are, what coding standard you follow and how well it’s enforced, etc.)?

            If so, then use C++. Otherwise,

            Do we need good C++ libraries to ease our job?

            If so, then use C++, but meanwhile always remember what you are doing – if your code doesn’t really need all the fancy abstractions, then try not to get sucked into them; don’t use class or templates just because you’re writing code in a .cpp file and using a C++ compiler.

            Otherwise, use C, but then you might wonder why not just use the C core of C++. The same reason as always: people get easily sucked into fancy language features even when they don’t really know if they’re going to help – I can’t tell you how many times I wrote a bunch of classes only to find out “what the heck are these classes for?”. So, if you can stick to the C core or C with class part of C++ and keep simple things simple, or if your code needs a migration path from C to C++, use C++ then, but be very careful. On the other hand, if you need neither abstraction mechanisms in your code nor quality C++ libraries because what you’re doing is so simple that you don’t even need convenient components like containers or strings, or you decide that the benefit C++ can bring you in your project is minor to an extent that it’s not even worth taking the risk, or you just simple don’t have enough people that can use C++ in a proper way, then maybe you should stick to C.

            The bottom line: keep simple things simple (but remember that simplicity can be achieved by using high-level libraries); use abstractions when necessary (and even then, make spare use of it; follow good design principles and established good practices).

            posted on 2007-09-15 10:20 志華 閱讀(227) 評(píng)論(0)  編輯 收藏 引用


            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


            <2011年1月>
            2627282930311
            2345678
            9101112131415
            16171819202122
            23242526272829
            303112345

            導(dǎo)航

            統(tǒng)計(jì)

            常用鏈接

            留言簿(1)

            隨筆分類

            隨筆檔案

            文章檔案

            搜索

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            中文字幕一区二区三区久久网站| 中文字幕精品久久| A级毛片无码久久精品免费| 久久国产免费直播| 久久久不卡国产精品一区二区 | 91久久精品无码一区二区毛片| 久久免费的精品国产V∧| 久久久久亚洲AV无码专区首JN | 久久夜色精品国产www| 青青青青久久精品国产h久久精品五福影院1421 | 人妻无码精品久久亚瑟影视| 久久福利资源国产精品999| 久久久久久综合网天天| 久久亚洲精品成人AV| 国产亚洲精品自在久久| 18岁日韩内射颜射午夜久久成人| 一本伊大人香蕉久久网手机| 日本精品一区二区久久久| 成人久久免费网站| 一本色道久久88加勒比—综合| 久久青青国产| 蜜臀av性久久久久蜜臀aⅴ| 99久久这里只有精品| 久久久这里有精品中文字幕| 亚洲AV无码一区东京热久久| 99久久国产热无码精品免费| 青青草国产97免久久费观看| 久久夜色精品国产噜噜亚洲AV| 94久久国产乱子伦精品免费| 怡红院日本一道日本久久 | 久久精品国产久精国产| 99热都是精品久久久久久| 久久精品国产亚洲AV影院| 国产亚州精品女人久久久久久| 狠狠色婷婷久久综合频道日韩 | 国产99久久精品一区二区| 久久久久亚洲AV成人网| 久久无码人妻一区二区三区午夜| 国内精品久久久久久久亚洲| 亚洲国产精品久久电影欧美| 久久无码一区二区三区少妇|