亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

Chinaunix

標題: 關于c++ [打印本頁]

作者: flyeon    時間: 2007-05-30 10:56
標題: 關于c++
我總覺得,系統(tǒng)級編程c能做,應用級的java等能做,c++是不是有點多余?
而且認為c++比較難,在unix下,c與系統(tǒng)api接口又那么自然,用c++我還覺得不方便。
當然,對于系統(tǒng)級的大項目,應該是c++的最好應用場合了吧
作者: converse    時間: 2007-05-30 11:02
什么方便用什么,什么順手用什么,什么合適用什么,不要為了用什么而去用什么....
作者: flyeon    時間: 2007-05-30 11:05
但學習要花時間啊,總得選一樣精通一些吧。
一直想學c++,但實際中沒應用,還是了解不深入
作者: langue    時間: 2007-05-30 11:09
.

http://www.google.com/search?hl=zh-CN&q=C%2B%2B+applications
希望不要產生偏見和誤會

.
作者: converse    時間: 2007-05-30 11:11
原帖由 flyeon 于 2007-5-30 11:05 發(fā)表
但學習要花時間啊,總得選一樣精通一些吧。
一直想學c++,但實際中沒應用,還是了解不深入


如果目前工作上用不上,可以暫時不學,我前一陣想學學shell,但是目前工作中用的比較少,所以暫時放下了,手邊備著一本shell的書,有需要的時候隨時查查看看,大家都很累沒可能為一些目前暫時用不到的知識花費精力,而且如果用不上很容易就會忘記的,相反如果工作中或者平時用的上很快就會上手.

當然,以上的方法不適用于那些對某個知識相當感興趣喜歡鉆研之的人.

現(xiàn)在我自己在底下一般花時間學以下的內容:1)工作里面馬上可以用的上的,比如unix,網絡編程,2)打基礎的知識,比如算法,OS原理等.
作者: flyeon    時間: 2007-05-30 11:19
主要希望有一些有用的技術的積累,也許將來用得著。
c++項目是多啊,比如ace。
只是,這些項目非要用c++么,這些項目可以分別用c和java很好的實施吧?考慮到應用的性能要求和開發(fā)要求,是不是可以將所有這些項目分成可以用c和java分別實施而性能接近現(xiàn)有c++開發(fā)的呢?
作者: flyeon    時間: 2007-05-30 11:22
比如我曾經想用gtk+和c++寫程序,但覺得別扭。gtkmm呢,發(fā)布又要帶上gtkmm的庫,我希望別人不去多下這個庫(這樣會妨礙程序的推廣)。
結果還是用c和gtk+。
作者: converse    時間: 2007-05-30 11:24
>>主要希望有一些有用的技術的積累,也許將來用得著。

我覺得這個問題的答案還是取決于你,你如果能保證自己有時間有精力有興趣去鉆研一門暫時用不上的技術,那么可以進行,否則,三天打魚兩天曬網,很快就會忘記,最后什么都沒有留下.

不是什么技術都要鉆研的,尤其是現(xiàn)在這個年代.

以上是我的觀點,LZ可以自己想想,僅供參考.
作者: flyeon    時間: 2007-05-30 11:33
呵呵。
能得到有經驗的朋友的建議感謝都來不及。
作者: MMMIX    時間: 2007-05-30 12:03
原帖由 converse 于 2007-5-30 11:24 發(fā)表
>>主要希望有一些有用的技術的積累,也許將來用得著。

我覺得這個問題的答案還是取決于你,你如果能保證自己有時間有精力有興趣去鉆研一門暫時用不上的技術,那么可以進行,否則,三天打魚兩天曬網,很快就會 ...

對頭,一門技術想要精通(甚至只是熟悉)非一朝一夕可以做到,三天打魚兩天曬網簡直就等同于浪費時間。
作者: flyeon    時間: 2007-05-30 12:24
但是由于對自己職業(yè)的規(guī)劃,考慮到將來的發(fā)展(興趣都不說了),掌握現(xiàn)在自己沒接觸的技術很重要,不是么。
畢竟很多人做著收入不高,人人都會做的事。
作者: langue    時間: 2007-05-30 12:28
哎,不是一直說么,國家培養(yǎng)人才,人才也要處理好個人喜好與國家需要的關系。其實從長遠的角度看,無論站在個人還是國家的立場上,這個還是十分有道理的。
作者: unixpm    時間: 2007-05-30 12:30
口水無聊找抽帖,呵呵
作者: langue    時間: 2007-05-30 12:35
原帖由 unixpm 于 2007-5-30 12:30 發(fā)表
口水無聊找抽帖,呵呵


口水不要緊,每個人因為說話時候口腔形狀以及肌肉運動等原因都可能導致部分唾液溢出。

我想樓主完全可以就技術細節(jié)進行討論,比如細致探討一下 C 和 C++ 在某些技術細節(jié)上的異同。上次不是討論過一個 lvalue 還是 rvalue 的問題嗎,我覺得這個很好,一些地方大家平常不怎么注意的問題,在這里提一下,我覺得會很不錯。

.
作者: flyeon    時間: 2007-05-30 12:40
技術細節(jié),倒是很少發(fā)現(xiàn)連google上都搜不到的。至少我這個層次的人的問題不至于難到那個程度。

心里有疑問就可以問,不是么。不違反版違,怎么叫找抽呢
c++的書看了不少,從別人的說法看,就是上了規(guī)模的項目用c++更便于開發(fā)維護。但我沒做過,我想,至少有人做過大型的c項目和c++項目吧,他們的親身體會可以告訴我為什么要選c++而不是c或java。
作者: MMMIX    時間: 2007-05-30 12:47
原帖由 flyeon 于 2007-5-30 12:40 發(fā)表
心里有疑問就可以問,不是么。

不是,至少是不大禮貌(在網絡上)。許多通過簡單查資料就可以解決的問題是不應該問的。
作者: flyeon    時間: 2007-05-30 12:56
原帖由 MMMIX 于 2007-5-30 12:47 發(fā)表

不是,至少是不大禮貌(在網絡上)。許多通過簡單查資料就可以解決的問題是不應該問的。
呵呵,是么。雖然有這么多c++項目,我就是不明白為什么人們要選擇c++。
作者: langue    時間: 2007-05-30 13:07
.

我認為 “上了規(guī)模的項目”,這里 “上了規(guī)! 本來就不好定義。

再者 C 和 C++ 說到底還是程序設計思想上的差異最大,是本質差異。C++ 比 C 多了 “基于對象”、“面向對象” 和 “泛型編程” 的思想,可以說,對 C 用到的程序設計思想做了補充。

● 其一,利用 C 和 C++ 都可以進行 “面向過程”、“基于對象”、“面向對象” 和 “泛型” 的程序設計,但 C++ 自身提供了一些設施,這些設施使得在 C++ 中完成某些任務(特別是面向對象的程序設計)變得相對容易一些。

● 其二,某些應用已經具有了經典的開發(fā)思維,想打破這種思維定式并不容易。比如操作系統(tǒng)的開發(fā),通常人們很容易想到 “應該用 C”。其實不然,以使用 C++ 為主的操作系統(tǒng)已經不是什么新鮮事了,大家有興趣可以去尋找一下關于 l4 系列的資料,也可以參考 UnixLite 項目,后者是國內的。

● 其三,我們在技術上應當精益求精。有志于此的技術愛好者們會利用自己的時間,進行廣泛而深入的技術研究與探討。可以思考一下,C 與 C++ 有哪些異同?都有哪些優(yōu)越性和不足的地方?和其它的程序設計語言是否有相通之處呢?有否能夠拿來借鑒的地方?能否提出一些新的思想呢?這樣無論時代如何變遷,不管采用哪種程序設計語言,我們的技術都是在不斷革新的,這樣我們的目的就真正達到了。

.
作者: flyeon    時間: 2007-05-30 13:15
呵呵,主要是因為我沒有c++方面的經驗,所以詢問一下。
此貼我就此打住,要不又來些口水戰(zhàn)。
作者: langue    時間: 2007-05-30 13:17
原帖由 flyeon 于 2007-5-30 13:15 發(fā)表
呵呵,主要是因為我沒有c++方面的經驗,所以詢問一下。
此貼我就此打住,要不又來些口水戰(zhàn)。


歡迎您在獲得相關經驗后還來本版做些交流。
作者: flyeon    時間: 2007-05-30 13:30
來這永遠是學習,在中國,chinaunix里的很多大俠們都是無人能出其右了
作者: ypxing    時間: 2007-05-30 14:46
其實, 大家更應該從"面向過程"和"面向對象"的角度去比較C和C++

它們帶給大家的主要是思考,分析和解決問題的角度不同

"面向過程"的語言一般來說是直接面向問題的,以算法和數(shù)據結構為中心
而"面向對象"的語言相對來說更加符合人們的建模習慣,適合將現(xiàn)實中的東東
抽象成類,然后利用類之間的交互等等來解決問題

用C或C++并不重要,都可以解決問題
但是,大家不要在使用C++或java的時候,還以C的觀點和習慣來解決問題就好了

也就是說,不要帶著"面向過程"的觀點和方法去使用"面向對象"的語言
作者: langue    時間: 2007-05-30 15:04
原帖由 ypxing 于 2007-5-30 14:46 發(fā)表
其實, 大家更應該從"面向過程"和"面向對象"的角度去比較C和C++

它們帶給大家的主要是思考,分析和解決問題的角度不同

"面向過程"的語言一般來說是直接面向問題的,以算法和數(shù)據結構為中心
而"面向對象"的語言相對來說更加符合人們的建模習慣,適合將現(xiàn)實中的東東
抽象成類,然后利用類之間的交互等等來解決問題

用C或C++并不重要,都可以解決問題
但是,大家不要在使用C++或java的時候,還以C的觀點和習慣來解決問題就好了

也就是說,不要帶著"面向過程"的觀點和方法去使用"面向對象"的語言


呵呵,那么我糾正一下自己先前的說法。C++ 不是 “面向過程” 的,而是 “過程化” 的,這是 C++ 的本質。

C++ is a procedural programming language rather than a procedure-oriented one.

.
作者: duanjigang    時間: 2007-05-30 16:05
大項目還是C++好點
作者: wuxiangzhi    時間: 2007-05-30 16:05
俺和LZ一樣困惑,有人解惑沒有?
作者: zarcoder    時間: 2007-05-30 16:33
大家更應該從"面向過程"和"面向對象"的角度去比較C和C++

具有面向對象或者面向過程屬性的是程序員,與具體語言無關
作者: benlan    時間: 2007-05-31 13:26
現(xiàn)在覺得c++有點多余了,現(xiàn)在c++存在的理由是有很多以前的項目,開源或非開源的項目,
如果一個新的項目,用c++就不是好的選擇了,
.net的效率已經很高了,jvm的效率也在一點點的提供,內存正白菜價,c++做新項目沒太大必要

曾經看好c++用來做嵌入式,把c取代掉用來做嵌入式,前面一個c++項目的內存泄漏查起來,那簡直是一種災難。用c++做嵌入式項目,平白給系統(tǒng)增加很多不必要的復雜性
作者: zhujiang73    時間: 2007-05-31 14:35
標題: 回復 27樓 benlan 的帖子
原帖由 benlan 于 2007-5-31 13:26 發(fā)表
現(xiàn)在覺得c++有點多余了,現(xiàn)在c++存在的理由是有很多以前的項目,開源或非開源的項目,
如果一個新的項目,用c++就不是好的選擇了,
.net的效率已經很高了,jvm的效率也在一點點的提供,內存正白菜價,c++做新項 ...


java 不能支持多語言這一點不如 .net  。如果 Linux 上的 .net 兼容環(huán)境(如 Mono 等)好用,我現(xiàn)在就換成 C# ,可是 Mono 成熟了嗎,沒有。所以我現(xiàn)在主要用 C++ ,用 C++  編程比用 C  編程還是要簡單一些。
作者: gieta    時間: 2007-05-31 15:04
各種語言都有自己的特點,它們都有各自的應用場合,lz說的c和java在不同方面都可以代替c++,也是有道理的,但是當我們同時需要c和java的一些特性的時候,我們選什么呢?比如在游戲領域,c++就有很大的市場,主要的開發(fā)一般都是c++加上一些腳本語言來做的。個人覺得學什么并不重要,重要的是要深入的學習,我現(xiàn)在用java開發(fā),但是我一直在學習c++,有空就看一些c++方面的書籍,c++非常的優(yōu)雅。不論是java還是c++,哪怕是c都還是再向前發(fā)展的,它們中都有很多值得學習的優(yōu)點,就說c++再泛型方面吧,java和.net還是停留在向c++學習的階段。把一門語言吃透了,學習其他的語言速度是很快的。靜下心來學才是最重要。
作者: antigloss    時間: 2007-05-31 19:46
原帖由 ypxing 于 2007-5-30 14:46 發(fā)表
其實, 大家更應該從"面向過程"和"面向對象"的角度去比較C和C++

... ...

也就是說,不要帶著"面向過程"的觀點和方法去使用"面向對象"的語言

C++ 不僅僅是面向對象的語言。
作者: ypxing    時間: 2007-05-31 20:05
原帖由 antigloss 于 2007-5-31 19:46 發(fā)表

C++ 不僅僅是面向對象的語言。



不過它的出現(xiàn)應該主要是為了體現(xiàn)面向對象的思想
作者: antigloss    時間: 2007-05-31 20:07
原帖由 ypxing 于 2007-5-31 20:05 發(fā)表



不過它的出現(xiàn)應該主要是為了體現(xiàn)面向對象的思想

設計之初的確如此,所以那時叫做 C with class
作者: benlan    時間: 2007-06-01 00:27
原帖由 zhujiang73 于 2007-5-31 14:35 發(fā)表


java 不能支持多語言這一點不如 .net  。如果 Linux 上的 .net 兼容環(huán)境(如 Mono 等)好用,我現(xiàn)在就換成 C# ,可是 Mono 成熟了嗎,沒有。所以我現(xiàn)在主要用 C++ ,用 C++  編程比用 C  編程還是要簡單一些。



支持多語言,只是ms把世界上的vb程序員(曾經世界上最多的程序員)繼續(xù)抓在手上的一個手段而已。每個語言都有自己的特點,如果需要(比如共用以前的開源資源),我寧可從新開始學這個語言,這樣子才純粹。

c++編程比c難很多,你覺得比c簡單可能是把c++當成c的過程來使,然后有個stl就覺得簡單了而已,其實這樣子應該算c++的門都沒進


c只要學通了 c程序設計和c專家編程,基本就能把程序寫的很好
作者: MMMIX    時間: 2007-06-01 00:33
原帖由 benlan 于 2007-6-1 00:27 發(fā)表
c只要學通了 c程序設計和c專家編程,基本就能把程序寫的很好

編程要是這么簡單就好嘍

[ 本帖最后由 MMMIX 于 2007-6-1 10:58 編輯 ]
作者: Sorehead    時間: 2007-06-01 10:52
  同意MMMIX的說法,c要是真這么簡單就好了,有時候越是貌似簡單的東西越復雜,用得越久就越覺得自己懂得東西太少。當然,c++引入了很多新的概念,同樣也不簡單,但并不能因此就認為其它語言就簡單。
  我用過c和java,對c++基本不了解,其實我對java也不怎么了解,因為工作需要使用java,好長一段時間后和同事聊天才發(fā)現(xiàn)自己壓根就是亂用java,因為我是用面向過程的方法來寫java程序。當然,程序依然能正確執(zhí)行,但卻違背了語言本身的最大初衷。
  做技術久了,對語言的認識也在加深,其實每種語言都有自己特定的使用環(huán)境,都有他們的缺點和優(yōu)點,所以不能對一種語言簡單的就蓋棺定論。語言都有相似性,一門語言精通了,其它的也能觸類旁通,入門相對就比較簡單,但要達到精通的地步還是需要時日的。
  本人不大贊同拿c和c++語言進行比較,因為比較兩個層次的東西本身立足點就不對。此外,過于專注于語言本身,我認為是有些本末倒置了,語言只是我們技術人員與計算機操作系統(tǒng)打交道的工具,計算機的基礎理論知識才是關鍵和核心。
作者: MMMIX    時間: 2007-06-01 10:59
原帖由 Sorehead 于 2007-6-1 10:52 發(fā)表
  同意MMMIX的說法,c要是真這么簡單就好了,

呃……其實我是想說“編程要是這么簡單就好了”
作者: zhujiang73    時間: 2007-06-01 13:34
標題: 回復 33樓 benlan 的帖子
支持多語言,只是ms把世界上的vb程序員(曾經世界上最多的程序員)繼續(xù)抓在手上的一個手段而已。每個語言都有自己的特點,如果需要(比如共用以前的開源資源),我寧可從新開始學這個語言,這樣子才純粹。

c++編程比c難很多,你覺得比c簡單可能是把c++當成c的過程來使,然后有個stl就覺得簡單了而已,其實這樣子應該算c++的門都沒進


c只要學通了 c程序設計和c專家編程,基本就能把程序寫的很好


每個語言都有自己的特點,但應該可以為其它語言提供一個簡單統(tǒng)一的接口,這樣用一種語言寫的庫模塊就可以用其它的語言調用,語言的特色應該體現(xiàn)在模塊內部,不應該體現(xiàn)在模塊接口上。與你合作的程序員只需要了解接口就可以調用你寫的模塊,他不用關心你的模塊是用什么語言寫的?纯  gtk 的相關開發(fā)人員為了讓 gtk 支持多種語言寫了多少包裝代碼,你就知道直接支持多語言的系統(tǒng)是多可愛了。

C++  內置的面向對象,模板等功能的卻可以讓編程容易很多。關于我 C++  入沒入門,請看我的大作:(趁機炒作 一下 ) “C++ 簡單遠程調用中間件設計”  
http://blog.chinaunix.net/u/21585/showart_290864.html

[ 本帖最后由 zhujiang73 于 2007-6-1 14:53 編輯 ]
作者: benlan    時間: 2007-06-01 22:59
原帖由 zhujiang73 于 2007-6-1 13:34 發(fā)表


每個語言都有自己的特點,但應該可以為其它語言提供一個簡單統(tǒng)一的接口,這樣用一種語言寫的庫模塊就可以用其它的語言調用,語言的特色應該體現(xiàn)在模塊內部,不應該體現(xiàn)在模塊接口上。與你合作的程序員只需要了 ...



看了下大作,先敬仰一下,這樣的東東我寫不出來,樓上強人。

不過只有幾個.h文件,看不出實質的東西,用了繼承,模板和運算符重載,stl等,看不到實現(xiàn),不清楚里面的實現(xiàn)是c++過程的還是對象的,要不就到cu把大作open一下,讓大家也學習。
作者: zhujiang73    時間: 2007-06-01 23:31
標題: 回復 38樓 benlan 的帖子
原帖由 benlan 于 2007-6-1 22:59 發(fā)表
看了下大作,先敬仰一下,這樣的東東我寫不出來,樓上強人。

不過只有幾個.h文件,看不出實質的東西,用了繼承,模板和運算符重載,stl等,看不到實現(xiàn),不清楚里面的實現(xiàn)是c++過程的還是對象的,要不就到 ...


blog 文章附件中的 *.cc 文件就是實現(xiàn), 包括庫和例子程序, 本來就是 open 的。
作者: zhujiang73    時間: 2007-06-04 11:22
標題: 轉貼一篇文章,展示一下 C++ 的幾個重要特性,看懂這個 C++ 就算基本懂了。
大家可以試試用 C  實現(xiàn)類似的功能,對大師應該不是問題,但是對像我這樣功力不足的,還是  C++  好用一些。

http://www.stlchina.org/twiki/bin/view.pl/Main/BoostSource_any

Boost源碼剖析之:泛型指針類any之海納百川
作者:ppLiu(劉未鵬)

C++是強類型語言,所有強類型語言對型別的要求都是苛刻的,型別一有不合編譯器就會抱怨說不能將某某型別轉換為某某型別,當然如果在型別之間提供了轉換操作符或是標準所允許的一定程度的隱式轉換(如經過非explicit構造函數(shù)創(chuàng)建臨時變量的隱式轉換或是在int,long這些基本型別間的)又另當別論。總的說來,為了保持型別安全,C++有嚴厲的要求。然而有時候程序員可能有這樣的需要:

int i;
iong j;
X x; //假設X為用戶定義的類
any anyVal=i;
... //use anyVal as a int value
anyVal=j;
... //use anyVal as a long value
anyVal=x;
... //use anyVal as a long value

考慮這樣的一個“泛型指針類”該如何設計是很有趣的事情。

1.它本身不能是模板類,因為如果它是模板,你必須為它的具現(xiàn)化提供模板參數(shù)。而事實上你并不想這樣做。你想讓同一個對象接受任意型別的數(shù)據。在上面的代碼中這個對象是anyVal。然而,如果你必須為它提供模板參數(shù),那么上面的代碼看起來就會像這樣:

any<int> anyIntVal=i;
any<long> anyLongVal=j;
...

這顯然已經喪失了anyVal的優(yōu)勢----以單個對象接受所有型別的數(shù)據。與其這樣還不如直接寫:

int anyIntVal=i;
int anyLongVal=j;

所以,any不能是模板類。

2.它必須提供某些有關它所保存的對象型別的信息。

3. 它必須提供某種方法將它保存的數(shù)值“取出來”。

事實上,Boost庫已經提供了這樣的類boost::any,下面我就為你講述它的原理及構造。

首先,any類里面一定要提供一個模板構造函數(shù)和模板operator=操作符。因為你必須允許用戶寫出:

any any_value(val); //val 的型別為任意的
any_value=val1; //val1 型別也是任意的

這樣的代碼。

其次,數(shù)據的存放之所是個問題,顯然你不能將它保存在any類中,那會導致any類成為模板類,后者是明確不被允許的。數(shù)據應該動態(tài)存放,即動態(tài)分配一個數(shù)據的容器來存放數(shù)據,而any類中則保存指向這個容器的指針,明確地說,是指向這個容器的基類的指針,這是因為容器本身必須為模板,而any類中的指針成員又必須不是泛型的(因為any不能是泛型的,所以any中所有數(shù)據成員都不能是泛型的),所以,結論是:為容器準備一個非泛型的基類,而讓指針指向該基類。

下面就看一看boost庫是如何具體實現(xiàn)這兩點的。

//摘自”boost/any.hpp”
class any
{
        public:
        class placeholder    //泛型數(shù)據容器holder的非泛型基類   
        {                    
                public: // structors
                virtual ~placeholder() //虛析構函數(shù),為保證派生類對象能用基類指針析構
                {}
                public: // queries
                virtual const std::type_info & type() const = 0; //提供關于型別的信息
                virtual placeholder * clone() const = 0;  //復制容器
        };
        template<typename ValueType>
        class holder : public placeholder   //
        {
                public: // structors
                holder(const ValueType & value) //
                : held(value)
                {}
                public: // queries
                virtual const std::type_info & type() const
                {
                        return typeid(ValueType);  //typeid返回std::typeinfo對象引用,后者包含任意
                        //對象的型別信息如name,還提供operator==操作符
                        //你可以用typeid(oneObj)==typeid(anotherObj)來比
                        //兩個對象之型別是否一致
                }
                virtual placeholder * clone() const
                {
                        return new holder(held);  //改寫虛函數(shù),返回自身的復制體
                }
                public: // representation
                ValueType held;  //數(shù)據保存的地方
        };//類定義結束
        
        placeholder * content;   //指向泛型數(shù)據容器holder的基類placeholder的指針
        template<typename ValueType>
        any(const ValueType & value)
        : content(new holder<ValueType>(value)) //模板構造函數(shù),動態(tài)分配數(shù)據容器并調用其構
        //造函數(shù)
        {}
        ...
        template<typename ValueType>
        any & operator=(const ValueType & rhs)    //與模板構造函數(shù)一樣,但使用了swap慣用手法
        {
                any(rhs).swap(*this); //先創(chuàng)建一個臨時對象any(rhs),再調用下面的swap函數(shù)進行底層
                //數(shù)據交換,注意與*this交換數(shù)據的是臨時對象,所以rhs的底層
                //數(shù)據并未被更改,只是在swap結束后臨時對象擁有了*this的底
                //層數(shù)據,而此時*this也擁有了臨時對象構造時所擁有的rhs的數(shù)
                //據的副本。然后臨時對象由于生命期的結束而被自動析構,*this
                //原來的底層數(shù)據隨之煙消云散。
                return *this;
        }
        any & swap(any & rhs)   //swap函數(shù),交換底層數(shù)據
        {
                std::swap(content, rhs.content); //只是簡單地將兩個指針的值互換
                return *this;
        }
        ~any()  //析構函數(shù)
        {
                delete content; //釋放容器,用的是基類指針,這就是placeholder需要一個虛
                //析構函數(shù)的原因
        }
        ...
};

這雖然并非any的全部源代碼,但是所有重要的思想已經表露無遺。剩下的部分只是一些簡單的細節(jié),請參見boost庫的原文件。

“但是等等!”,你急切的說:“你失去了型別的信息。”唔...的確,當賦值的模板函數(shù)返回后你也就失去了關于型別的信息。考慮下面你可能想要寫出的代碼:

int i=10;
boost::any anyVal=i;
int j=anyVal; //error,實際上你是想把anyVal賦給另一個int型變量,這應該以某種方式被允
//許,但決不是在any類中提供轉換操作符,因為你事先并不知道要用anyVal來承
//載何種型別的變量,所以轉換操作符無從給出。

當轉換操作符的設想徹底失敗后,我們只能借助于某些“外來”的顯式轉換操作。就向static_cast<>一樣。Boost提供了any_cast<>,于是你可以這樣寫:

int j=any_cast<int>(anyVal);

事實上,any_cast的代碼是這樣的:

template<typename ValueType>
ValueType any_cast(const any & operand)
{
        const ValueType * result = any_cast<ValueType>(&operand);//調用any_cast針對指針的版
        //本。
        if(!result)  //如果cast失敗,即實際 保存的并非ValueType型數(shù)據,則拋出一個異常
        throw bad_any_cast(); //派生自std::bad_cast
        return *result;
}

而any_cast針對指針的版本是這樣:

template<typename ValueType>
ValueType * any_cast(any * operand)
{
        return operand && operand->type() == typeid(ValueType) //這個型別檢查很重要,后面會
        //對它作更詳細的解釋
        1    ? &static_cast<any::holder<ValueType> *>(operand->content)->held:0; //這兒有個向下
        //型別轉換
}

這兩個any_cast版本應該很好理解。后版本中的型別檢查是必要的,如果沒有這個檢查,考慮以下代碼:

int i=10;
boost::any anyVal=i;
double d=any_cast<double>(anyVal); //如果沒有那個型別檢查,這將通過編譯且運行期通常也不
//會出錯,但是
//對d的賦值將會是非常奇怪的情形。

這將通過編譯,且運行期通常竟然也不會出錯,下面我為你解釋為什么會這樣。

boost::anyVal=i;其實將anyVal.content指針指向了一個holder對象(請回顧上面的代碼)。然后any_cast(anyVal)實際上調用了any_cast<>針對指針的重載版本,并將anyVal的地址傳遞過去,也就是轉到1處,因為調用的是any_cast,所以1處的代碼被編譯器特化為

2  static_cast<any::holder<double> *>(operand->content)->held

但是前面說過,operand->content實際指向的是any::holder,所以這個static_cast<>是“非法”的,然而事實是:它能通過編譯!原因很簡單,holder和holder都是placeholder的基類。將基類指針向派生類指針轉換被認為是合法的。但這卻釀成大錯,因為表達式2的型別將因此被推導為double!原先holder只給int held;成員分配了sizeof(int)個字節(jié)的內存,而現(xiàn)在卻要將int型的held當作double型來使用,也就是說使用sizeof(double)個字節(jié)內存。所以這就相當于:

int i=10;
double* pd=(double*)(void*)&i;
double d=*pd; //行為未定義,但通常卻不會出錯,然而隱藏的錯誤更可怕,你得到的d的值幾
//乎肯定不是你想要的。

使用typeinfo讓我們有可能在運行時發(fā)現(xiàn)這種型別不符并及時拋出異常。但有個違反直觀的事情是上面的那行錯誤的代碼仍能通過編譯,并且你也無法阻止它通過編譯,因為holder和holder都是placeholder的基類。所以只能期望程序員們清楚自己在做什么,要不然就給他個異常瞧瞧。

使用boost::any實現(xiàn)virtual template成員函數(shù)

如你所知,C++中沒有提供virtual template function。然而有時候你的確會有這種需要,any可以一定程度上滿足這種需要,例如,

class Base
{
        public:
        virtual void Accept(boost::any anyData)
        {
                ...
        }
};
class Derived:public Base
{public:
        virtual void Accept(boost::any anyData)
        {
                ...
        }
};

這樣的Accept函數(shù)能夠接受任意類型的數(shù)據,并且是virtual函數(shù)

作者: mycomput    時間: 2007-06-04 17:00
標題: 支持c
覺得還是把c語言學習的精一點,至于其他的淺嘗輒止,需要的時候再學習上手也很快




歡迎光臨 Chinaunix (http://www.72891.cn/) Powered by Discuz! X3.2