2016-12-24 13 views
2

私はDelphiで作成したプロジェクトを翻訳しようとしています。オブジェクトのように、一般的に宣言することができます:C程度スタックとヒープのC++オブジェクトの寿命

//I have the control of the object and I MUST delete it when it's not needed anymore 

male := THuman.Create(); 
try 
// code 
finally 
male.Free; (get rid of the object) 
end; 

読書Stroustrup氏の著書++ Iは常に回避策があるので(ショートで)彼の言語はfinallyブロックを必要としないことを理解しています。オブジェクトが作成され、その後、ブロック{... code ...}が、私は、オブジェクトの人生をコントロールすることができ

  • THuman* male = new THumanを終了したときにスコープ外になるさ

    1. THuman male;いる:私はクラスを作成したい場合は今、私は2つの方法がありますそして本は最初のアプローチを使用することを示唆してdelete


    (たとえボットでそれを破壊しますhは大丈夫ですが)私はDelphiのバックグラウンドから来て、私は2番目のメソッドを使いたいと思います(私はオブジェクトのコントロールを持っています)。

    質問があります。私はC++がオブジェクトに対して持っている方法とオンラインで読むことの2つの方法の違いを理解できません。もっと混乱します。メソッド1がスタックにメモリを割り当て、ヒープ上にメソッド2を割り当てると正しいのでしょうか?

    メソッド2(私たちはヒープにあります)にオブジェクトに値NULLを割り当てても、削除を呼び出す必要がありますか?

    たとえば、Delphiではヒープ上にのみインスタンスを作成でき、Freeはオブジェクトを削除します(C++ではdeleteなど)。

  • +0

    https://en.wikipedia.org/wiki/Resource_acquisition_is_initialization –

    +1

    [C++オブジェクトのライフサイクルとは何か?](http://stackoverflow.com/questions/17121305/what-is-the- – Borgleader

    +1

    可能な限りポインタと動的割り当てを避けてください。あなたがそれらをよく理解していないと、問題や奇妙な行動につながるだけです。自動ストレージ( "スタック"のローカル変数)は安全で、現在の(またはネストされた)ブロック内の変数のみが必要な場合にはうまく機能します。現代のC++では、多形性を除いてポインタはまったく必要ありません。 –

    答えて

    3

    は(あなたが言うように、スタックに作成したが、それはほとんどのコンパイラによって選ばれた実装技術である)自動寿命を持っている彼らは外に出たら、それらは自動的に解放されます範囲。

    2- new(ヒープで作成されたオブジェクト、つまりほとんどのコンパイラの実装方法)で作成されたオブジェクトのライフタイムは、プログラマが管理する必要があります。削除はポインタをNULLに設定することではないことに注意してください。単純なルールは、次のとおり

    • newnew[](動的配列の作成)が1つのみdelete[]

    PSと一致しなければならない1つのみdelete

  • と一致しなければなりません。 が一致しましたは、プログラムのランタイムで1対1のオカレンスに関係します。必ずしもコードそのものではありません。の新しいオブジェクトをいつどこで削除するかを制御できます。

  • +0

    C++では一般的にポインターを避けることをお勧めしますか?ポインタはもっと "Cスタイル"です。 –

    +0

    @RaffaeleRossiこれは意見に基づくものであり、そういうものもあります。他の人(私のような人たち)はポインタが非常に強力なイディオムであることを自由に感じるように伝えます。他のものはスマートポインタの使用を促進するが、IMOは別の懸念事項である。 –

    +0

    マウンテンバイクや都市バイクのようなものだと言えますか?どちらも同じですが、人々は必要な用途に応じてどちらか一方を好む –

    2

    私は方法1がスタック上にメモリを割り当て、ヒープ上で方法2を指定すると正しいのでしょうか?方法2では

    • はい

    (私たちはヒープにいる)私がオブジェクトに値NULLを割り当てた場合、私はまだ削除呼び出す必要がありますか?

    • 代わりに生のポインタのsmartpointersを使用することを検討してください。スマートポインタはポインタリソースを扱い、より安全に使用できるオブジェクトです。 ただし、スマートポインタを使用できない場合は、ポインタにdeleteを呼び出して、NULLを割り当てる前に、ヒープから前に割り当てられたメモリを解放するようにしてください。そうしないと、リソースが漏洩します。あなたは方法2(我々はヒープにいる)私がオブジェクトに値NULLが割り当てられている場合にはvalgrind
    +0

    "yes"と答えると、方法1では、いくつかのストレージがスタックに割り当てられていることを明確にしてから、オブジェクトのコンストラクタがヒープにもっと割り当てることができます。 –

    +0

    また、C++仕様では、ローカル変数が「スタック」に格納されているとは特に言いません。ローカル変数を扱う最も一般的な方法ですが、C++仕様では「自動」ストレージしかないとしか言​​いません。コンパイラは、ローカル変数を別々に格納することを選択することがあります。 –

    2

    を実行することができ、あなたのプログラムのメモリ管理を確認するには、私はまだ削除呼び出す必要がありますか?

    あなたがメモリをリークする前に削除すると、NULLポインタで削除を呼び出すと、segフォルト(アプリケーションクラッシュ)が発生します。

    スタックオブジェクトを使用するのが最善の方法ですが、オブジェクトの存在を管理する必要がある場合は、上記のようにスマートポインタ(unique_ptr、shared_ptr)を使用してください。

    注:「リークメモリ」とは、この領域が失われたことを意味します。プログラムからアクセスできず、OSによって解放されません。 newで作成されていないショート

    の1-オブジェクトで

    関連する問題