2016-09-18 2 views
5

Я следующий код:Преобразовать символ * в строке &

#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 - отдельный объект. Объект std::string не поддерживает указатель на созданный объект char *. Существует много способов создать std::string. Фактическая строка принадлежит объекту. Если std::string построен из строки буквального символа, он копируется в std::string. Итак, если буквальная строка символов поступает из буфера, а затем буфер изменяется, он не влияет на std::string.

+0

Конструктор 'std :: string' принимает параметр' const char * 'для параметра. Я ошибаюсь? – skypjack

+0

Нет, вы не, @skypjack. Вот почему я написал «can take», а не «принимает». –

5

Эта линия:

const string &s2 = argv[0]; 

Создает новый экземпляр string, копирование содержимого argv[0], и связывает ссылку на него. Позже эта копия выводится, которая теперь не связана с фактическим значением argv[0].

Временное временное строение объектов, созданное в цитируемой строке, расширяется до объема блока, поскольку к нему была создана ссылка на константу. См. Больше на: Does a const reference prolong the life of a temporary?

+0

Спасибо за ссылку! –

1

В обоих случаях код просит компилятор построить временный объект std::string, содержимое которого является копией argv[0]. Хотя это весело и, может быть, полезно посмотреть на детали, из которых он работает, и почему, с точки зрения написания кода, беспорядок со временными не является необходимым и приводит к путанице.Просто создайте объект:

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

Линия

const string &s2 = argv[0]; 

равно:

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

Так s2 содержит константную ссылку на временную строку, которая скопированный контент из ARGV [ 0].

Смежные вопросы