Каковы различия в инициализации строки в C ++? - PullRequest
21 голосов
/ 03 февраля 2010

Есть ли разница между

std::string s1("foo");

и

std::string s2 = "foo";

?

Ответы [ 4 ]

27 голосов
/ 03 февраля 2010

Да и нет.

Первый инициализируется явно, а второй инициализируется копией. Стандарты позволяют заменить второе на первое. На практике полученный код одинаков.

Вот что происходит в двух словах:

std::string s1("foo");

Строковый конструктор вида:

string ( const char * s );

вызывается для s1.

Во втором случае. Временное создается, и упомянутый конструктор более раннего вызывается для этого временного. Затем вызывается конструктор копирования. например:

string s1 = string("foo");

На практике вторая форма оптимизируется, чтобы иметь форму первой. Я не видел компилятор, который не оптимизирует второй случай.

13 голосов
/ 03 февраля 2010

На первый взгляд, первый вызывает конструктор const char* для инициализации s1. Второй использует конструктор const char* для инициализации временного значения, а затем использует конструктор копирования, передавая ссылку на это временное значение, для инициализации s2.

Тем не менее, стандарт явно разрешает то, что называется "разрешением копирования", что означает, что, как говорит АраК, второе может быть юридически заменено первым , даже если конструктор копирования имеет наблюдаемые побочные эффекты , поэтому что изменение влияет на вывод программы.

Однако, когда эта замена сделана, компилятор все равно должен проверить, что класс имеет доступный конструктор копирования. Таким образом, потенциальная разница в том, что вторая форма требует, чтобы конструктор копирования вызывался, даже если компилятор не должен вызывать его. Очевидно, у std::string есть такой, так что в этом случае это не имеет значения, но для других классов это может быть.

3 голосов
/ 03 февраля 2010

разницы нет

0 голосов
/ 03 февраля 2010

Первый лучше.

Второй создаст экземпляр и назначит значение по умолчанию (""). Тогда будет второе назначение: "foo". Итак, 2 задания вместо 1 ...

...