以下はすべて、素朴なコンパイラが行うことです。もちろん、プログラムの動作を変更しない限り、コンパイラは自由に最適化を行うことができます。
string a;
a = "hello!";
最初に、空の文字列を含むように a を初期化します。(長さを 0 に設定し、他の 1 つまたは 2 つの操作を行います)。次に、すでに設定されている長さの値を上書きして、新しい値を割り当てます。また、現在のバッファーの大きさと、さらにメモリを割り当てる必要があるかどうかを確認するために、チェックを実行する必要がある場合もあります。
string *a;
a = new string("hello!");
...
delete(a);
new を呼び出すには、OS とメモリ アロケータがメモリの空きチャンクを見つける必要があります。それは遅いです。次に、すぐに初期化するので、最初のバージョンのように、何かを 2 回割り当てたり、バッファーのサイズを変更したりする必要はありません。その後、何か問題が発生し、delete を呼び出すのを忘れて、割り当てが非常に遅い文字列に加えて、メモリ リークが発生します。だからこれは悪い。
string a;
a = "less";
a = "moreeeeeee";
最初のケースと同様に、最初に a を初期化して空の文字列を含めます。次に、新しい文字列を割り当ててから、別の文字列を割り当てます。これらのそれぞれは、より多くのメモリを割り当てるために new の呼び出しを必要とする場合があります。各行には長さも必要であり、場合によっては他の内部変数を割り当てる必要があります。
通常、次のように割り当てます。
string a = "hello";
1行で、最初にデフォルトで初期化してから必要な値を割り当てるのではなく、初期化を1回実行します。
プログラムのどこにも無意味な空の文字列がないため、エラーも最小限に抑えられます。文字列が存在する場合は、必要な値が含まれています。
メモリ管理については、google RAII。つまり、string は new/delete を内部的に呼び出して、バッファーのサイズを変更します。つまり、new で文字列を割り当てる必要はありません。文字列オブジェクトは固定サイズで、スタックに割り当てられるように設計されているため、スコープ外になるとデストラクタが自動的に呼び出されます。デストラクタは、割り当てられたメモリが解放されることを保証します。これにより、ユーザー コードで new/delete を使用する必要がなくなり、メモリ リークが発生しなくなります。