來源:http://www.cnblogs.com/chio/archive/2008/10/06/1305145.htmlhtml
先來個區別說明:賦值操做是在兩個已經存在的對象間進行的,而初始化是要建立一個新的對象,而且其初值來源於另外一個已存在的對象。編譯器會區別這兩種情 況,賦值的時候調用重載的賦值運算符,初始化的時候調用拷貝構造函數。若是類中沒有拷貝構造函數,則編譯器會提供一個默認的。這個默認的拷貝構造函數只是 簡單地複製類中的每一個成員。 下面看例子。
c++中初始化和賦值操做差異是很大的。
對於基本數據類型差異不大:
好比:
int a = 12; // initialization, copy 0X000C to a
a = 12; // assignment, copy 0X000C to a
可是對用戶自定義的數據類型好比String 初始化和賦值就差異很大:
class String ...{
public:
String( const char *init ); // intentionally not explicit!
~String();
String( const String &that );
String &operator =( const String &that );
String &operator =( const char *str );
void swap( String &that );
friend const String // concatenate
operator +( const String &, const String & );
friend bool operator <( const String &, const String & );
//...
private:
String( const char *, const char * ); // computational
char *s_;
};
初始化的構造過程比較簡單:先分配一個足夠大的空間而後填充上數據:
String::String( const char *init ) ...{
if( !init ) init = """";
s_ = new char[ strlen(init)+1 ];
strcpy( s_, init );
}
析構過程更簡單:
String::~String() ...{ delete [] s_; }
可是若是賦值操做就複雜多了:
String &String::operator =( const char *str ) ...{
if( !str ) str = """";
char *tmp = strcpy( new char[ strlen(str)+1 ], str ); // 多了中間變量
delete [] s_; // 多了刪除s_;
s_ = tmp; // 多一個賦值操做!如今是指向字符的指針,若是是個大對象,效率的差異可想而知.
return *this;
}c++
C++初始化語法的不一致性:數組
C語言確實很優雅,整個語言的設計簡潔一致。而在C++中,有一個讓人詬病的問題就是變量初始化的不一致性。數據結構
C語言中的初始化,都是用花括號進行,簡單美觀:函數
C++天然也兼容了C語言的初始化機制。然而,C++的Class乃至STL都不支持。它們要用不一樣的方式來初始化, 甚至根本不可以直接初始化, 只能使用運行時的賦值。
好比Class:this
沒法初始化。而若是不初始化的話,全部的成員而處於無政府狀態,這顯然很不讓人放心。因而,C++提供了專門用於Class的初始化方式--構造函數:spa
有了構造函數,能夠在構造函數的初始化列表中對成員進行初始化。但是很明顯,這裏頭仍是有一個陷阱,默認構造初始化和非默認構造初始化的調用方式是不一致的。默認構造函數不能用括號來調用,不然編譯器將會發瘋:設計
它會把上面的語句當作是函數聲明,然後面調用的時候就會出錯,而錯誤信息可能會讓你抓狂一下。可是這樣也就算了,恰恰 new 能夠接受有括號和沒括號兩種寫法:指針
再來講說初始化列表。初始化列表,事實上,也只能支持簡單的標量類型,諸如int,bool,指針之類的;複雜點的,如數組、結構,很差意思,不支 持--只能在構造函數體中進行賦值。還有一個很迷糊初學者的問題是,成員初始化的順序僅依賴於成員定義的順序,而不是初始化列表中的順序。
再好比STL容器,這下好象更慘,連構造函數都幫不上忙了,除了初始化一個空的容器,或是複製一下別的容器,咱們只能作用默認構造函數進行初始化。咱們拿數組和vecotr作個比較:htm
再複雜一點的數據結構,那單單賦值程序就要寫上老長,並且還很差看。還要記得調用。這對於僅僅是簡單的設置一些初值的用途來講,太過於煩瑣。
橫向比較,此次好象C++還不會太落伍,只有C和動態語言提供了初始化特性,其它支持OO高級語言好象都是學C++的。如Java, C#(注C#3.0開始提供初始化功能)...
C++能不能作到簡潔一致的實始化呢?
Boost的assign庫作了許多有益的工做。使用assign庫,至少如今能夠初始化了:
若是是賦值,也能夠簡略不少:
不過,也僅能如此了。assign通過許多努力,也僅能支持容器的初始化,並且還不夠漂亮。
C++0x已肯定提供與C一致的初始化功能。 Initialer lists Initializer Lists for Standard Containers Initializer lists WP wording 等草案就是爲了這個目的服務的。
若是使用C++0x,那麼程序的初始化將變得清晰和一致:
這好象是C++欠了十多年的債吧。