Подтвердить что ты не робот

Объявление строки С++

Я изучаю С++ с самого начала, и я не получаю тему целых строк.

В чем разница между следующими тремя кодами?

  • std::string s = std::string("foo");
  • std::string s = new std::string("foo");
  • std::string s = "foo";
4b9b3361

Ответ 1

std::string s = std::string("foo");

Создает временный объект std::string, содержащий "foo" , затем присваивает его s. (Обратите внимание, что компиляторы могут уклоняться от временной. Временный elison в этом случае явно разрешен стандартом С++.)

std::string s = new std::string("foo");

Это ошибка компилятора. Выражение new std::string("foo") создает std::string в свободном хранилище и возвращает указатель на std::string. Затем он пытается присвоить возвращаемый указатель типа std::string* на s типа std::string. Конструкция класса std::string предотвращает это, поэтому сбой компиляции.

С++ не является Java. Это не так, как обычно создаются объекты, потому что если вы забудете delete возвращенный объект std::string, вы будете утечки памяти. Одним из основных преимуществ использования std::string является то, что он автоматически управляет базовым буфером строк, поэтому new - это своего рода поражения этой цели.

std::string s = "foo";

Это по существу то же самое, что и # 1. Он технически инициализирует новую временную строку, которая будет содержать "foo" , а затем присваивает ее s. Опять же, компиляторы, как правило, удаляют временные (и на самом деле почти все не-глупые компиляторы в настоящее время фактически исключают временные), поэтому на практике он просто создает новый объект с именем s на месте.

В частности, он вызывает конструктор преобразования в std::string, который принимает аргумент const char*. В приведенном выше коде конструктор преобразования должен быть не explicit, в противном случае это ошибка компилятора. Конструктор преобразования фактически не explicit для std::string s, поэтому приведенное выше компилируется.

Вот как обычно инициализируется std::string. Когда s выходит за пределы области видимости, объект s будет уничтожен вместе с базовым буфером строк. Обратите внимание, что следующее имеет тот же эффект (и является другим типичным способом std::string), в том смысле, что он также создает объект с именем s, содержащий "foo" .

std::string s("foo");

Однако существует тонкая разница между std::string s = "foo"; и std::string s("foo");, одна из которых заключается в том, что конструктор преобразования может быть либо explicit, либо не explicit в приведенном выше случае.

Ответ 2

std::string s = std::string("foo");

Это называется инициализацией копирования. Это функционально то же самое, что и прямая инициализация

std::string s( "foo" );

но первый требует, чтобы конструктор копирования был доступен, а компиляторы могли создать временный объект, но большинство из них вернутся к временной и прямой конструкции s, содержащей "foo".


std::string s = new std::string("foo");

Это не скомпилируется, потому что new возвращает указатель. Чтобы он работал, вам нужен тип s как std::string *. Затем строка динамически выделяет объект std::string и сохраняет указатель в s. Вам понадобится delete, как только вы закончите использовать его.


std::string s = "foo";

Это почти то же самое, что и первое. Это инициализация копирования, но она имеет дополнительное ограничение. Для этого требуется, чтобы класс std::string содержал конструктор не explicit, который принимает const char *. Это позволяет компилятору неявно построить временный объект std::string. После этого семантика идентична случаю 1.

Ответ 3

  • Создает временный строковый объект и копирует значение s
  • Не компилируется, new std::string("foo") возвращает указатель на некоторую вновь выделенную память. Чтобы это сработало, вы должны объявить s как указатель на строку std::string* s.
  • Создает строку из C-строки.

Вы должны использовать третий вариант в большинстве случаев, если не во всех случаях.

Ответ 4

1 создаст временную переменную (правую сторону), затем вызовет оператор присваивания, чтобы присвоить значение s

2 создаст экземпляр std::string в куче и вернет указатель на него и не удастся выполнить назначение, потому что вы не можете назначить указатель на не указательный тип

3 построит std::string и инициализирует его с помощью const char*

Ответ 5

В номере 1 вы создаете временную строку, используя конструктор, а затем присваиваете ее s. Номер 2 даже не компилируется. На номер 3 вы создаете новую строку, а затем присваиваете ей значение.