web-dev-qa-db-ja.com

オブジェクトの作成:「新規」の有無にかかわらず

可能性のある複製:
newとwithoutを使用してオブジェクトをインスタンス化することの違いは何ですか

これはおそらく基本的な質問であり、すでに質問されている可能性があります(たとえば、 here )。まだ私はそれを理解していません。お願いします。

次のC++クラスを検討してください。

class Obj{
    char* str;
public:
    Obj(char* s){
        str = s;
        cout << str;
    }
    ~Obj(){
        cout << "Done!\n";
        delete str;        // See the comment of "Loki Astari" below on why this line of code is bad practice
    }
};

次のコードスニペットの違いは何ですか:

Obj o1 ("Hi\n");

そして

Obj* o2 = new Obj("Hi\n");

前者がデストラクタを呼び出すのに、後者は(deleteを明示的に呼び出すことなく)呼び出さないのはなぜですか?

どちらが好ましいですか?

115
M.S. Dousti

両方とも異なることをします。

最初は、自動保存期間でオブジェクトを作成します。作成され、使用され、現在のブロック({ ... })が終了すると範囲外になります。オブジェクトを作成する最も簡単な方法であり、int x = 0;を記述するときと同じです。

2番目はdynamic storage durationでオブジェクトを作成し、2つのことを許可します:

  • オブジェクトは自動的にスコープから外れないため、オブジェクトのライフタイムを細かく制御できます。キーワードdeleteを使用して明示的に破棄する必要があります。

  • オブジェクトの作成は実行時に行われるため、実行時にのみ既知のサイズの配列を作成します。 (ここでは、動的配列の割り当ての詳細には触れません。)

どちらも優先されません。どちらが最も適切であるかについて、あなたが何をしているかに依存します。

後者を使用する必要がない限り、前者を使用してください。

C++ブックでこれをかなりうまくカバーしているはずです。持っていない場合は、さらに購入しないでください、何度か購入して読むまで、 これら

がんばろう。


deletesはcharではないnew配列であるため、元のコードは壊れています。実際、nothingnewd Cスタイルの文字列。文字列リテラルから来ました。 deleteingはエラーです(ただし、コンパイルエラーは生成されませんが、実行時の予測できない動作です)。

通常、オブジェクトには、それ自体がdeleteでなかったものをnewingする責任はありません。この動作は十分に文書化されている必要があります。この場合、ルールは完全に破られています。

最初はオブジェクトに自動保存期間を割り当てます。つまり、オブジェクトが定義されているスコープから出ると、オブジェクトは自動的に破棄されます。

2番目は動的ストレージ期間を持つオブジェクトを割り当てました。つまり、明示的にdeleteを使用してそうするまで、オブジェクトは破棄されません。

19
Jerry Coffin