2013-07-07 146 views
1

我有以下代碼:C++構造初始化

struct Y { 
     string& s1; //string s1; throws no error 
     Y(string src) : s1(src) { cout<<"s1: "<<s1<<endl; } 
     void show(){ cout<<s1<<endl; } 
    }; 

    int main() 
    { 
     Y y1("Krypton"); 
     y1.show(); //run-time error 
    } 

y1.show()應顯示「氪」,但我得到一個運行時錯誤(由於S1是未初始化時y1.show()是爲叫什麼名字?)。

Q1。爲什麼s1在構造函數初始化列表中已經初始化時會被初始化? Q2。如果我使用字符串s1,爲什麼不會得到相同的錯誤;而不是參考?

任何幫助將不勝感激。

Regards,

Jay。

+1

描述* actual *錯誤通常是一個好主意,而不是僅僅說「我得到一個運行時錯誤」。 – jalf

回答

1

要初始化從一個臨時的引用的本地副本。如果你希望struct Y的實例擁有一個實際的字符串,而不僅僅是一個引用,你需要一個string類型的成員變量,而不是引用字符串。

Q1。爲什麼s1在構造函數初始化列表中已經初始化時會被初始化?

它已被初始化,但是作爲對不再存在的字符串的引用。第二季度銷售價格指數爲:

Q2。如果我使用字符串s1,爲什麼不會得到相同的錯誤;而不是參考?

如果類包含一個字符串,那麼它不包含對存在的字符串的引用。

您認爲該參考文獻是參考文獻的字符串?

+0

謝謝。因此,如果我正確理解這一點,那麼引用成員指向構造函數執行完成後不存在的值。但引用變量必須在初始化列表中初始化。在那種情況下,我怎樣才能正確地初始化s1? – VivereJay

+0

只要這行代碼完成'Y y1(「Krypton」);',它就不復存在了。因爲你傳遞了一個'const char *'構造函數,所以它必須創建一個臨時字符串。一旦不再需要,臨時就不復存在。當你引用一個對象時,你有責任確保該對象在對象停止存在後不被解除引用! –

1

s1設置爲引用src,它是一個臨時對象,並在構造函數存在時被銷燬。

當您s1一個字符串,它是不依賴於src

0

因爲你的構造Y(string src)接受模板值,s1參考這個模板值,然後調用show()打印值女巫是構造後destroty。

答:

1.因爲參考的價值s1是構造後銷燬。

2.如果您使用string s1代替string& s1,巫分配src喲當S1調用構造函數,show()將打印件值S1的

如果你想普林「氪」,你可以改變Y(string src)Y(string& src)

0

在你的情況,你可以初始化臨時成員變量這樣

struct Y 
{ 
    string& s1; 

    Y(string& src) 
     : s1(src) 
    { 
     cout<<"s1: "<<s1<<endl; 
    } 

    void show() 
    { 
     cout<<s1<<endl; 
    } 
}; 

int main() 
{ 
    string s1_real = "Krypton"; 
    Y y1(s1_real); 
    y1.show(); 

    return 0; 
} 

注意

  1. 構造函數需要一個引用(字符串& src不是字符串src)。因爲如果使用「string src」,它將是一個臨時變量,只要函數堆棧展開並且s1最終成爲懸掛參考,它就會被銷燬。如果使用「字符串& src」,則不會創建新的內存位置; src指向s1_real,因此s1最終指向s1_real。

  2. 您創建了一個用於創建y1的變量(s1_real)。這是因爲你不能把一個臨時變量的引用(你只能拿一個const引用,在這種情況下src和S1也必須聲明爲const引用)

務必注意,壽命y1必須小於s1_real,否則y1.s1最後成爲懸掛參考

+0

謝謝約翰!我有同樣的想法,但是錯過了將ctor改爲接受對main()中定義的字符串的引用。所以它仍然崩潰,再次由於上面解釋的所有原因:) – VivereJay