Все, что делает наивный компилятор, будет следующим. Конечно, до тех пор, пока это не изменит поведение программы, компилятор может выполнить любую оптимизацию.
string a;
a = "hello!";
Сначала вы инициализируете, чтобы содержать пустую строку. (установите длину в 0 и одну или две другие операции). Затем вы назначаете новое значение, перезаписывая значение длины, которое уже было установлено. Может также потребоваться выполнить проверку, чтобы увидеть, насколько велик текущий буфер, и нужно ли выделять больше памяти.
string *a;
a = new string("hello!");
...
delete(a);
Для вызова new требуется, чтобы ОС и распределитель памяти находили свободный кусок памяти. Это медленно. Затем вы немедленно инициализируете его, поэтому вы ничего не назначаете дважды и не требуете изменения размера буфера, как в первой версии.
Затем происходит что-то плохое, и вы забываете вызвать delete, и у вас возникает утечка памяти, в дополнение к к строке, которую выделять очень медленно. Так что это плохо.
string a;
a = "less";
a = "moreeeeeee";
Как и в первом случае, вы сначала инициализируете a, чтобы содержать пустую строку. Затем вы назначаете новую строку, а затем другую. Каждый из этих может потребовать вызова new, чтобы выделить больше памяти. Каждая строка также требует длины и, возможно, других внутренних переменных, которые должны быть назначены.
Обычно вы бы выделяли его так:
string a = "hello";
Одна строка, выполнить инициализацию один раз, а не сначала инициализацию по умолчанию, а затем присвоить нужное значение.
Это также сводит к минимуму ошибки, потому что у вас нет бессмысленной пустой строки в вашей программе. Если строка существует, она содержит требуемое значение.
Об управлении памятью, Google RAII.
Короче говоря, строка вызывает new / delete для внутреннего изменения размера буфера. Это означает, что никогда не нужно выделять строку с новым. Строковый объект имеет фиксированный размер и предназначен для размещения в стеке, так что деструктор автоматически вызывается , когда выходит из области видимости. Затем деструктор гарантирует освобождение любой выделенной памяти. Таким образом, вам не нужно использовать новый / удалить в своем коде пользователя, что означает, что вы не потеряете память.