Есть ли любое различие между
std::string s1("foo");
и
std::string s2 = "foo";
?
Да и Нет
Первый инициализируется явно, а второй инициализируется копией. Стандарты позволяют заменить второе на первое. На практике полученный код такой же.
Вот что вкратце происходит:
std::string s1("foo");
Конструктор строк формы:
string ( const char * s );
вызывается для s1
.
Во втором случае. Создается временный объект, и для него вызывается упомянутый более ранний конструктор. Затем вызывается конструктор копирования. например:
string s1 = string("foo");
На практике вторая форма оптимизирована, чтобы иметь форму первой. Я не видел компилятора, который бы не оптимизировал второй случай.
Первый лучше.
Второй создаст экземпляр и присваивает значение по умолчанию («»). Тогда будет присвоение Secodn: «Foo». Так что 2 задания вместо 1 ...
На первый взгляд, первый вызывает конструктор const char *
для инициализации s1
. Второй использует конструктор const char *
для инициализации временного значения, а затем использует конструктор копирования, передавая ссылку на это временное значение, для инициализации s2
.
Тем не менее, стандарт явно разрешает то, что называется «исключение копирования», что означает, что, как говорит AraK, второй может быть законно заменен первым , даже если конструктор копирования имеет наблюдаемые побочные эффекты , поэтому что изменение влияет на вывод программы.
Однако, когда эта замена сделана, компилятор все равно должен проверить, есть ли у класса доступный конструктор копирования. Таким образом, потенциальная разница в том, что вторая форма требует, чтобы конструктор копирования был вызываемым, даже если компилятор не должен его вызывать. Очевидно, что в std :: string
он есть, поэтому в данном случае это не имеет значения, но для других классов может.