2016-09-18 44 views
5

我有以下代碼:轉換的char *字符串和

#include <iostream> 
using namespace std; 

int main(int argc, char *argv[]) 
{ 
    string &s1 = argv[0];   // error 
    const string &s2 = argv[0];  // ok 

    argv[0] = "abc"; 
    cout << argv[0] << endl;  // prints "abc" 
    cout << s2 << endl;    // prints program name 
} 

我收到s1以下錯誤:

invalid initialization of reference of type 'std::string& {aka std::basic_string<char>&}' from expression of type 'char*' 

那麼爲什麼編譯器接受s2

有趣的是,當我爲argv[0]指定一個新值時,s2不會改變。編譯器是否忽略它是一個引用並且複製該值?爲什麼會發生?

我在Code :: Blocks 16.01(mingw)中寫這個。有/無-std=c++11

+1

你會說'argv [0]'是一個'std :: string'嗎? – Biffen

+0

「那爲什麼編譯器接受s2?」由於隱式轉換。 http://stackoverflow.com/questions/4553896/conversion-of-char-to-string –

回答

6

那爲什麼編譯器接受s2呢?

由於恆定的參考可以綁定到一個暫時的,std::string有一個構造可以採取char *爲參數。

該賦值構造了一個所謂的「臨時」對象,並綁定了一個常量引用。

有趣的是,當我給argv [0]分配一個新值時,s2不會 更改。

它爲什麼要改變? s2是一個單獨的對象。 A std::string對象不保留指向創建它的char *的指針。有很多方法可以創建std::string。實際的字符串由對象擁有。如果std::string由文字字符串構造而成,則將其複製到std::string中。因此,如果文字字符串來自緩衝區,並且隨後修改了緩衝區,則它對std::string不起作用。

+0

一個'std :: string'的構造函數接受一個'const char *'作爲參數。我錯了嗎? – skypjack

+0

不,你不是,@ skypjack。這就是爲什麼我寫了「可以採取」,而不是「採取」。 –

5

這條線:

const string &s2 = argv[0]; 

創建新string例如,複製的argv[0]的內容,並結合參考它。之後,輸出該副本,現在與argv[0]的實際值無關。

在帶引號的行中創建的臨時字符串對象生存期被擴展到該塊的範圍,因爲形成了一個const引用。更多信息請參見:Does a const reference prolong the life of a temporary?

+0

謝謝你的鏈接! –

1

在這兩種情況下,代碼都會要求編譯器構造一個臨時對象,其內容爲argv[0]的副本std::string。雖然看起來很有趣,也許有用,但是從實際編寫代碼的角度來看,弄清臨時對象並不是必要的,並且會導致混淆。只是創建一個對象:

std::string s1 = argv[0]; 
1

const string &s2 = argv[0]; 

等於:

const string &s2 = std::string(argv[0]); 

所以S2包含const引用到一個臨時字符串,複製從的argv [內容0]。