Хотя конечный результат всех трех методов один и тот же (строка будет назначена переменной), существуют определенные фундаментальные различия, которые идут глубже, чем синтаксис. Я рассмотрю все 3 сценария, на которые ссылаются ваши 3 строки:
Первый случай: s1 - пример прямой инициализации. Прямая инициализация охватывает ряд разностных сценариев, которые определяются следующим образом:
Инициализация с помощью непустого списка выражений в скобках.
Здесь s1 не имеет типа данных класса, но тип std::string
данных, поэтому стандартное преобразование будет иметь место, чтобы преобразовать тип данных в круглых скобках в сорте-неквалифицированные версии s1, который const *char
.Cv-unqualified означает, что нет такого классификатора, как (const) или (изменчивый) прилагается к переменной. Обратите внимание, что в случае прямой инициализации это намного более разрешительная, чем копирование-инициализация, которая является предметом s2. Это связано с тем, что инициализация копирования относится только к конструкторам и функциям преобразования, определенным пользователем, которые являются non_explicit (т. Е. Неявным). С другой стороны, прямая инициализация рассматривает неявные и явные конструкторы и пользовательские функции преобразования.
При переходе вторая строка s2 является примером инициализации копии. Проще говоря, он копирует значение с левой стороны вправо. Это пример:
, когда именованная переменная (автоматическая, статическая или поточно-локальная) не ссылочного типа T объявляется с инициализатором, состоящим из знака равенства, за которым следует выражение.
Процесс, охватываемый этим методом, тот же. Поскольку s2 не имеет тип данных класса, а тип данных std::string
, он будет использовать стандартное преобразование для преобразования значения строки с правой стороны в значение типа const *char
слева. Однако, если функция объявлена явно, стандартное преобразование не может быть выполнено в отличие от инициализатора копии, и компиляция кода завершится с ошибкой.
См. Некоторые примеры кода по сравнению с двумя типами инициализаций. Это должно очистить любые неурядицы сверху:
struct Exp { explicit Exp(const char*) {} }; // This function has an explicit constructor; therefore, we cannot use a copy initialization here
Exp e1("abc"); // Direct initialization is valid here
Exp e2 = "abc"; // Error, copy-initialization does not consider explicit constructor
struct Imp { Imp(const char*) {} }; // Here we have an implicit constructor; therefore, a copy initializer can be used
Imp i1("abc"); // Direct initialization always works
Imp i2 = "abc"; // Copy initialization works here due to implicit copy constructor
Переходя к третьему случаю, это даже не случай инициализации, это случай уступки. Как вы сказали в своих комментариях, переменная s3 инициализируется строкой по умолчанию. Эта строка заменяется на «Hello», когда вы используете знак равенства. Здесь происходит то, что когда s3 объявляется в string s3;
, вызывается конструктор по умолчанию для std::string
и задается строковое значение по умолчанию. Эта строка по умолчанию заменяется на привет в следующей строке, когда вы используете знак =.
Если мы смотрим на более эффективные с точки зрения скорости при работе, разница является предельной. Тем не менее, s1 занимает лучшее время, чтобы работать, если мы только делаем это:
int main(void)
{
string a("Hello");
}
Это произошло следующее время и память для компиляции и запуска:
время компиляции: 0,32 сек, абсолютное время работы: 0,14 сек, процессорное время: 0 сек, пиковая память: 3 Мб, абсолютное время службы: 0,46 сек
Если мы посмотрим на строки s2 кодированной следующим образом:
int main(void)
{
string a = "Hello";
}
Тогда общее время, необходимое для работы программы является: время
Компиляции: 0,32 сек, абсолютное время работы: 0,14 сек, процессорное время: 0 сек, пиковая память: 3 Мб, время абсолютного обслуживания : 0,47 с
Время выполнения, использующее инициализатор копии, принимает 0.01 секунд для запуска, чем прямой инициализатор. Разница существует, но маргинальная.
3-й случай с s3, если кодируются следующим образом:
int main(void)
{
string a;
a = "Hello";
}
имеет в общей сложности работает, пространство и время компиляции взят из:
Сборника Время: 0,32 сек, абсолютное время работы : 0,14 с, время процессора: 0 с, пик памяти: 3 Мб, абсолютное время обслуживания: 0,47 с
Я хотел бы указать что-то здесь: разница во времени между второй и третий методы, скорее всего, NOT ноль; скорее, это разница во времени менее 0,01 секунды, при этом третий метод занимает больше времени (s3). Это потому, что у него есть 2 строки кода для работы; один - объявление переменной, а другое - назначение строки переменной.
Надеюсь, это ответит на ваш вопрос.
Возможный дубликат [Есть ли разница в C++ между инициализацией копирования и прямой инициализацией?] (Http://stackoverflow.com/questions/1051379/is-there-a-difference-in-c-between-copy- initialization-and-direct-initializati) –
Также: [Инициализация и присвоение] (http://stackoverflow.com/questions/7350155/initialisation-and-assignment) –