論C++0x新標準:歡迎還是拒絕?
今天在CSDN上看到一篇文章,發現C++0x(或者稱C++11或者C++0B)確實有很多令人興奮的新特性,
搜索一番,看了Stroustrup的C++11FAQ,頗有感想,因此希望與大家共享一下。想必大家都有自己
的看法,歡迎探討。
1. 新特性展示,您是喜歡還是反感?
以下我想展示幾個目前可用的一些新特性,給不想花時間詳細了解的讀者一個直觀感受。
(我使用MINGW GCC 4.6.1,注意加--std=c++0x或者--std=gnu++0x)
在C++98中,我要循環一個vector<string>:
1 for(vector<string>::const_iterator itr = aVec.begin(); itr != aVec.end(); ++itr){
2 cout << *itr << endl;
3 }
而在新標準中,這樣就行了:
1 for(auto e : aVec){ cout << e << endl;}
這里展示了兩個特性,新的auto關鍵字和ranged for。auto在新標準中語義變了,成為了
編譯器自動推導類型的意思。而原來的auto關鍵字幾乎沒有什么作用,local stack變量就是
默認的,幾乎見不到auto的使用。新標準中,使用原來的語義要產生錯誤的!ranged for也
很好理解,就是學了Java或C#等語言的for循環,很方便。甚至可以這樣:
1 for(auto i : {1, 2, 3, 4, 5}) {cout << i << endl;}
所以新的代碼應該見到很多auto了,這并不是動態變量,而是簡化了繁冗的工作,讓編譯器
去做低級重復的事情。下面顯示三種比較現代的C++:
1 map<string, vector<int> > *myMap = new map<string, vector<int> >; // 最舊風格
2 shared_ptr<map<string, vector<int> > > myMap = new map<string, vector<int> >; // 舊風格
4 auto myMap = make_shared<map<string, vector<int>>>(); // 新風格
make_shared是一個庫函數,在VC2010中也能用,是一個非常方便的代替new的函數,直接返回
創建對象的shared_ptr。新標準推薦顯式使用智能指針,徹底杜絕delete。例如表達唯一擁有關系
就用unique_ptr,表達共享關系就用shared_ptr,表達弱引用就用weak_ptr,只有表達非擁有關系,
只是為了track一個對象的,才使用*。而且也不用擔心模板的右尖括號問題了。
還有一個小改動是值得注意的,就是類成員的初始化。大家知道在Java或C#中,變量初始話可以直接
在聲明時進行,而在C++中就必須在初始列表中,但是新標準也進行了改進,于是看以下代碼:
1 class A
2 {
3 static const int a = 3; // Ok in 89
4 static int a = 3; // Error: not const in 89
5 const int a = 3; // Error: not static in 89
6 int a = 3; // Error in 89 but Ok in 0x
7 public:
8 A():a(0){} // Ok in 89 but not necessary in 0x
9 }
C++0x還有一個大的改動及加上了語言級別的lambda函數。及可以在需要使用函數指針或函數對象(所謂functor)
的地方使用如下語法聲明一個匿名函數:
1 [](int a, int b){return a>b;}
這相當于把boost的lambda函數庫集成到語言中了,這樣有幾個好處,首先就是沒有外部依賴,
第二可能會降低模版導致的代碼體積增大或效率問題。總體上來說是個不錯的功能,以后C++的
界面庫就可以用類似的方法寫event handler了。
除了語言方面的一些列改進,標準庫更是增加了不少內容。最顯著的是thread、regex等,都是
對C++能力(跨平臺的基礎上)的大幅擴充。具體大家可以查資料,在這里只是簡單一提。
2. C++0x,一門新語言?
或許您已經查閱了很多C++0x相關的文章,或者您只是看了我上面簡短的介紹,您對
C++的演化抱有什么態度呢?我在CSDN等地看到的更多是抱怨,很多菜鳥認為過于復雜,
難于學習入門。C++他爸認為C++0x是一門新語言,在某種程度上,還真是。
我對C++也是經驗有限,個人感覺C++的發展喜憂參半。對于把C++當成C with classes
的人來說(大多數上點年紀的C++庫都是如此用C++的),完全用新語言寫的代碼,真的有種陌生
之感。我曾看到過一些大量使用模版的代碼,唯一的感覺就是不必要的復雜性,或者是語言
本身的無能,只能通過各種tricks來實現一些本該語言就能實現的東西。
C++的模式太廣了,如果是底層代碼,其實用C加上幾個類,就可以搞得很好;如果是應用
開發,C++嚴重缺少的一個特性就是垃圾收集,為了提高效率,減少內存錯誤,于是基于模版
的智能指針開始出現,就是為了在一個不適合做應用層開發的語言上提高易用性,又想
不損失效率,后果就是不必要的復雜性。比如類型操作,大的框架都有反射機制,C++一定
程度上也有,就是要損失效率,所以才有各種操作類型的模版。C++的模版真是物盡其用,
被開發到了一種無以復加的程度,結果呢,使用模版的程序,體積快速膨脹,錯誤信息基本
不可讀,極大增加了調試難度,同時語言的學習曲線變陡了。
C++的新標準旨在提高語言的易用性,一系列變化,很大程度上就是語法層面的改進,
其實本質的語義改變很少。另一個就是把boost中成熟的庫能加的都加進去(或者整合到語言
里面),于是現代版的C++就出爐了。所以本質上看,C++0x還不是一個新語言。
3. 從新標準看C++語言定位
C++基于C語言并與其兼容的情況,使得對應用開發來說,其代碼過于底層,開發效率
低。而現代流行的編譯型語言,例如C#或Java,隱藏了C++一些底層特征,而吸收了
其一些高層表達方式,加上強大的類庫支持,使得他們的易用性大大提高。如果利用Qt或者
wxWidgets,C++也可以相對容易地完成一些應用開發,但是最終的程序,并不一定
有很大的效率或體積優勢(有興趣的讀者可以比較一下CodeBlocks和SharpDevelop
兩個IDE的運行時內存和速度)。
那么C++到底怎么定位呢?C++0x似乎在向著應用開發方面發展,因為其試圖通過
智能指針隱藏C++內存管理的麻煩,用模版和類來實現各種高級語義,從而能夠直接
把問題映射為語言結構。標準庫也對Unicode、Threading、Atomic Operation、標準
容器、正則表達式等提供了完善的支持,我想把boost的FileSystem加進來,再有人
實現一個跨平臺的std::ui,那么C++可真可以和Java或C#坐一起了(或者是自降身份?)
作為一個偏向系統編程的語言,卻把泛型和lambda等高級語義作未來的方向,感覺
C++的定位還真是有點復雜(也有點混亂)。
其實做底層開發,把C++當做一個better C完全值得提倡。做游戲,用到的特性也就是類
的封裝,簡化C一些繁瑣的操作,因為很多C++特性用起來是會降低效率的。做界面等
應用開發,C++的很多特性,和大公司打造的龐大平臺(.Net或Java)相比,不論是優化、
語言特性、易用性,還是類庫支持,都是比不上的。有時候我感覺用C++的一個優勢是
不用強迫用戶安裝支持平臺,但是現在隨著Window7普及,.Net平臺都默認裝在那里了,
真沒有理由放著這么大好的資源不用,而用C++去做吃力不討好的事情。Python等動態
語言,隨著硬件的升級,其效率劣勢也逐漸消失,Ubuntu推薦的開發工具竟然是Python+
PyGTK,其開發速度和體驗,也是很好的,因為就像.Net之于Windows,Python現在
基本是所有現代Linux發行版默認安裝的語言了。你可能找不到gcc,但你一定可以用
Python。且Python作為一個語言,在各方面都是具有絕對優勢的。
這么看來,如果C++不對語言本身進行重大變革(變成一個新語言),又想通過各種方式
來提供高級語義,只能治標不治本,始終不適合所謂的高層開發(相對于底層)。
4. 歡迎還是拒絕?
現在C++11已經是標準了,只不過大多數編譯器還沒有完全實現而已。我們當然沒有選擇的
權利,但是C++還是向下兼容的,于是我們可以選擇是否使用新功能。
我還是很喜歡C++的,對于有些簡化編程的改進,真是舉雙手贊成。我甚至以后會一直打開
--std=c++0x的選項,用上所有能用的新特性。如果這就是C++,我就這樣用C++,但是
如果我寫C,我只會用C的功能,并且編譯成C模塊,ABI兼容性也是很好的。感覺現在
C++和C有點像雙重人格,亟待分為兩個(真正意義上不同的)語言,然后各自發展。
另外,C++的標準io庫還是謹慎為妙(尤其是用gcc),有時會出現莫名其妙的問題,
還是用C的stdio比較保險。且個人認為printf格式更加易用。
這些改進對于初學者可能不是好事,因為初學者直接學C++的話(就像C++老爸那樣,
直接把C++當新語言教),就會很費解,這些都是什么亂七八糟的東西。只有學過C,
或者學過C++的C子集,然后才能理解,例如,為什么這么多莫名奇妙的指針。因為
C++本質上還是C的系統模型。
C++老手可能會覺得,這些東西沒什么,只不過是把久以形成的編程習慣固定化了。我甚至
希望,以后C++的指針都默認是智能指針吧,這樣能省多少事啊,但是這就打破了對C的兼容性。
所以還是那句話,如果C++的語言本質沒有改變,減少痛苦的改進還是歡迎的,但是這對于
語言本身的發展并沒有太大的意義。如果C++能生成新的語言,有志發展成為不在虛擬機上的
大而全的開發平臺,就是另一回事了。

浙公網安備 33010602011771號