Объявление строки C ++ - PullRequest
26 голосов
/ 09 ноября 2011

Я изучаю C ++ с самого начала, и я не понимаю всю тему строк.

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

  1. std::string s = std::string("foo");
  2. std::string s = new std::string("foo");
  3. std::string s = "foo";

Ответы [ 5 ]

42 голосов
/ 09 ноября 2011
std::string s = std::string("foo");

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

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

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

C ++ - это не Java.Это не то, как объекты обычно создаются, потому что если вы забудете delete возвращенный объект std::string, вы потеряете память.Одним из основных преимуществ использования std::string является то, что он автоматически управляет нижележащим строковым буфером, так что new - это своего рода побеждает эту цель.# 1.Технически он инициализирует новую временную строку, которая будет содержать «foo», а затем присваивает ее s.Опять же, компиляторы, как правило, исключают временные (и фактически почти все не глупые компиляторы в настоящее время фактически исключают временные), поэтому на практике он просто создает новый объект с именем s на месте.

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

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

std::string s("foo");

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

3 голосов
/ 09 ноября 2011
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 содержал не-1022 * конструктор, который принимает const char *.Это позволяет компилятору неявно создавать временный объект std::string.После этого семантика идентична случаю 1.

2 голосов
/ 09 ноября 2011

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

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

3 создаст std :: string и инициализирует ее из const char*

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

Третий вариант следует использовать в большинстве - если не во всех - случаях.

1 голос
/ 09 ноября 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...