2017-07-02 9 views
2
ここ

基本的な例であるとは何ですか?コンストラクタをヒープまたはスタックに作成する違いは何ですか?

myclass * abc = new myclass() 

myclass abc 

違いは何ですか?両方の状況で、オブジェクトabcがスタックに作成されていますか?オブジェクトがヒープで作成されている場合、何が違いますか?答えから

、私は(正しくない場合は編集してください)ことを取る:我々はそれが外にあるときに、クラスの変数は削除されていない場合コンストラクタは、クラス(メンバー)

  • を初期化

    1. オブジェクトの作成をヒープにする必要があります。

  • +5

    あなたはオブジェクトが別の場所に格納されていることを意味しますか?また、ヒープに割り当てられたオブジェクトのポインタが必要ですか?おそらく、あなたを悩ましていることや、あなたが疑問に思っていることについて少し詳しく説明できますか? –

    +0

    そして、 'new'を使って割り当てられたオブジェクトの破壊を(手動で)管理する必要があります(他のオブジェクトは寿命が終わると自動的に破壊されます)。 – UnholySheep

    +0

    両方のコードでabcオブジェクトがスタックに作成されましたか?ヒープ内のコンストラクタを作成するとコードにどのような影響がありますか? –

    答えて

    5

    両方ケースabc自動メモリである(一般に「スタック」と呼ばれる)には、オブジェクトの同じ種類のものである:実施例abc

    • がスタックに格納されているポインタです。しかし、動的メモリ(通常は「ヒープ」と呼ばれる)に格納されるタイプmyclassの第2のオブジェクトがあります。オブジェクトポインタabcは、ヒープ内のオブジェクトを指します。
    • abcは、myclassです。これが作成される唯一のオブジェクトです。

    2つのアプローチの主な違いは、ダイナミックメモリで作成されたオブジェクトが、その内部で作成された関数より「寿命が長い」ことができることです。ポインタabcが有効範囲外になると、そのヒープオブジェクトはアクティブのままです。たとえば、コピーを作成せずに関数から返すことができます。

    +0

    @StelTeamポインタを使用してオブジェクトにアクセスします。これは構文が異なります。 'delete'を呼び出すことによって、オブジェクトを手動で削除する必要があります。 – dasblinkenlight

    +0

    あなたが助けてくれてありがとうございました –

    +0

    とポインタがスコープ外に出たらもう1つオブジェクトにアクセスする方法は? –

    1

    myclass * abc = new myclass();では、スタックとヒープ上のMyClassのインスタンス上のMyClassへのポインタを作成します。 myclass abc;では、スタック上にmyclassのインスタンスを作成します。

    多くの違いがありますが、ヒープが残っている間に現在のコンテキストを残したとき(関数からの戻りなど)にスタックが解放されることが最も単純です。したがって、最初の例では、myclassのインスタンスは、手動で解放するまでメモリに残りますが、2番目のオプションでは、書き込まれた関数またはコードブロックを終了すると自動的にクリアされます。

    1

    コンストラクタ呼び出しの観点からは、基本的に2つの違いはありません。どちらの場合も、クラスのデフォルトコンストラクタが呼び出されてオブジェクトが構築されます。 myclass * abc = new myclass()の場合、new演算子は新しく作成されたオブジェクトへのポインタを返します。

    しかし、主な違いはスタックメモリとヒープ(ダイナミック)メモリの概念にあります。 myclass * abc = new myclass()という式は、新たに作成されたオブジェクトのメモリをヒープから割り当て、myclass abcはスタックから割り当てます。この相違点の1つは、スタックに割り当てられた変数に対して、ヒープから要求したメモリを自分で割り当て、割り当てを解除する必要があることです。コンパイラはメモリの削除を行います。関数が戻るが、abc2のメモリは、コンパイラによって自動的に解放されると、この関数の場合、

    void fo() 
    { 
        myclass * abc1 = new myclass(); 
        myclass abc2; 
    
        // Use the declared variables. 
    
        // At the end, is everything OK? 
    } 
    

    次の簡単な関数を考えてみましょう。コンパイラはabc1ポインタも削除しますが、このポインタが指すメモリについては何も行いません。この微妙な機能により、この機能ではnotorious memoryのリークが発生します。 foアドレスの以下の修正版この間違い:

    void fo() 
    { 
        myclass * abc1 = new myclass(); 
        myclass abc2; 
    
        // At the end, manually free the memory that abc1 points to if it is not needed anymore 
        delete abc1 
    } 
    

    ウィキペディアは、それらについての詳細な情報を提供し、より多くの詳細を提供ヒープとスタックメモリの概念についてvery nice articleを持っています。

    +1

    ありがとう –

    関連する問題