直接初始化與復制初始化


這是C++中所支持的兩種初始化方式。 
復制初始化使用=符號,而直接初始化將初始化式放在圓括號中。 
(1)對於一般的內建類型,這兩種初始化基本上沒有區別。 
int a(5);//直接初始化 
int a=5;//復制初始化 
int a=int (5);//直接初始化 
(2)當用於類類型對象時,初始化的復制形式和直接形式有所不同:直接初始化直接調用與實參匹配的構造函數,復制初始化總是調用復制構造函數。復制初始化首先使用指定構造函數創建一個臨時對象,然后使用復制構造函數將那個臨時對象復制到正在創建的對象。 
string null_book = "9-999-99999-9 ";//copy-initialization 
string dots(10, '. ');//direct-initialization 
string empty_copy = string();//先direct,然后copy-initialization 
string empty_direct;//direct-initialization 
對於類類型對象,只有指定單個實參或顯式創建一個臨時對象用於復制時,才使用復制初始化。 
創建dots時,調用參數為一個數量和一個字符的string構造函數並直接初始化dots的成員。創建null_book時,編譯器首先調用接受一個C風格字符串形參的string構造函數,創建一個臨時對象,然后,編譯器使用string復制構造函數將null_book初始化為那個臨時對象的副本。 
empty_copy和empty_direct的初始化都調用默認構造函數。對前者初始化時,默認構造函數創建一個臨時對象,然后復制構造函數用該對象初始化empty_copy。對后者初始化時,直接運行empty_direct的默認構造函數。 

支持初始化的復制形式主要是為了與C的用法兼容。當情況許可時,可以允許編譯器跳過復制構造函數直接創建對象,但編譯器沒有義務這樣做。
通常直接初始化和復制初始化僅在低級別優化上存在差異。然而,對於不支持復制的類型,或者使用非explicit構造函數的時候,它們有本質區別:
ifstream file1("filename");//ok:direct initialization 
ifstream file2 = "filename";//error:copy constructor is private

//This initialization is okay only if the sales_item(const string&) constructor is not explicit 
Sales_item item = string("9-999-99999-9"); 
... 
item的初始化是否正確,取決於正在使用哪個版本的Sales_item類。某些版本將參數為一個string的構造函數定義為explicit。如果構造函數是顯示的,則初始化失敗;如果構造函數不是顯示的,則初始化成功。 

對於復制初始化,最顯示的調用手段就是使用“=”符號(這個時候應該成為復制初始化符號)。那么還有許多地方是隱式的調用。如參數傳遞時,函數返回時,初始化容器時! 
1)對於參數傳遞:我們知道除非是引用參數,否則就是一個使用上層對象復制初始化函數參數的過程。 
2)對於函數返回值:我們知道除非是引用返回,否則在return的那個語句就是使用函數內的對象,復制初始化一個上層對象(通常是臨時的,然后馬上有被用於)
3)在某些容器初始化的過程中如: 
vect<string> svec(5); 
這里的過程就是,先使用string默認構造出一個實例對象,然后使用這個對象,復制初始化其它的元素。這個過程是容器的實現細節,其實從外面看,可以理解為直接初始化。 
4)數組初始化,有時候使用這樣的語法: 
Sales_item primer_eds[]={ string("1231231"), 
string("3123123") 

可知這個過程,就是一個先調用直接初始化生成string,然后繼續隱式調用直接初始化生成Sales_item。最后使用復制初始化,給那個數組的各個元素初始化。
這兒是對復制構造函數和復制初始化的介紹: http://www.cnblogs.com/xkfz007/archive/2012/03/01/2376376.html
下面是一個測試構造函數的類:

#include <iostream>
using  namespace std;
class A{
friend ostream&  operator<<(ostream& os, const A& rhs);
     public:
        A( int a= 10):m_a(a){
            id=count++;
            cout<< " A(int a):id= "<<id<<endl;
        }
        A( const A& rhs):m_a(rhs.m_a){
            id=count++;
            cout<< " A(const A&rhs):id= "<<id<<endl;
        }
        A&  operator=( const A& rhs){
             if( this !=&rhs){
                id=count++;
                m_a=rhs.m_a;
            }
             return * this;
        }
        ~A(){
            cout<< " ~A:id= "<<id<<endl;
        }
     private:
         int m_a;
         int id;
         static  int count;
};
int A::count= 0;
ostream&  operator<<(ostream& os, const A& rhs){
    os<< " <A:m_a= "<<rhs.m_a<< " ,id= "<<rhs.id<< " > ";
     return os;
}
int main1(){
    A a1;
    cout<<a1<<endl;
    A a2=a1;
    cout<<a2<<endl;
    A a3;
    cout<<a3<<endl;
    a3=a2;
    cout<<a3<<endl;
    A a4(a3);
    cout<<a4<<endl;
return  0;
}
int main(){
    A a1,a2( 5),a3( 200);
    A b=A( 8000);
    cout<<b<<endl;
    A arr[]={a1,a2,a3}; 
     int i( 5),j= 5;
     int k= int();
    cout<<i<<j<<k<<endl;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM