2016-12-15 4 views
5

新しいクラスのインスタンスを複数作成する場合、各インスタンスのデストラクタを呼び出す必要がありますか、それとも一度呼び出すとインスタンスが破棄されますか(あいまいな/間違った用語を使用している場合はコンストラクタ/デストラクタは私はまだ完全に把握していない概念)。新しいクラスの各インスタンスを破棄する必要はありますか?

具体的には、これは私が協力しているコードです(スタイルが悪い場合は謝罪しなければなりません。私は学校の問題のアイディアを持っていて、コードをすぐに取りたいと思っていました)。

while(read >> f >> l >> t >> s >> sta >> acct >> bal) 
{ 
    cout << "test" << endl; 
    ptr[i] = new account(f,l,t,s,sta,acct,bal); 
    ptr[i]->printcontents(); 
    cout << "test" << endl; 
    i++; 
    cout << i << endl; 
} 

質問のために、これは3回繰り返されると仮定します。新しいアカウントの3つのインスタンスをすべて破棄するには、「アカウント」のデストラクタを一度呼び出す必要がありますか?これは良い練習ですか?

編集:自分の投稿の一部が途切れてしまったことに気がついたので、最後の数行を追加しましたが、すでに人々はその問題に対処しています。割り当てが私に指示するので、私がユーザーポインタである理由は純粋です。非常に率直に言って、私はこの時点でそれらを使用する際のポイントが見当たらないのですが、私は彼らが役に立つようになったところをどこかに仮定しています。私はまた、動的メモリ割り当ても割り当てに使用されることを追加する必要があります。

+2

使用スマートポインタ(すなわち 'shared_ptr' /' make_shared'または 'unique_ptr' /' make_unique')を閉じるようにデストラクタを呼び出して、あなたの 'の削除については気にしないでください必要新しい 'sインスタンス。 –

+4

いつも通り:すべての 'new'はちょうど1つの' delete'と 'new []'のちょうど1つの 'delete []'を必要とします。しかし、基本的には、newとnewを必要とすることはまずありません。 –

+4

本当の質問は、あなたがポインタを使って始めている理由です。 Javaから来たのですか?すべてのオブジェクトが 'new'で作成されていますか?あなたの 'account'オブジェクトの配列は実際の' account'オブジェクト*を格納することができます。 –

答えて

5

デストラクタが自動的に呼び出され、あなたがnewで動的にメモリを割り当てているない限り、あなたは通常、それを心配する必要はありません。

その場合、あなたは一度、各割り当てられたメモリのためdeleteを呼び出す必要がありますそれは必要ありません もっと。あなたはnew []で配列を割り当てている場合、あなたはdesallocationためdelete[]を使用する必要がありますことを

注:現代のC++では

int *a = new int[10]; // allocating an array of 10 integers 

//... 

delete[] a; // release memory 

、あなたはあなたのために仕事をする管理ポインタを検討すべきです。ような何か:

ここ
while(read >> f >> l >> t >> s >> sta >> acct >> bal) 
{ 
    cout << "test" << endl; 
    ptr[i] = std::make_unique<account>(f,l,t,s,sta,acct,bal); 
    ptr[i]->printcontents(); 
    cout << "test" << endl; 
    i++; 
    cout << i << endl; 
} 

std::make_uniqueが破壊されたときに関連するメモリ上で削除を呼び出しますstd::unique_ptr戻ります。


最後のポイント:本当にポインタが必要ですか?あなたの例から言うのは難しいが、あなたの使用状況に応じて、あなたにも静的に割り当てられたオブジェクトを作成することがあります。

while(read >> f >> l >> t >> s >> sta >> acct >> bal) 
{ 
    cout << "test" << endl; 
    ptr[i] = account(f,l,t,s,sta,acct,bal); 
    ptr[i].printcontents(); 
    cout << "test" << endl; 
    i++; 
    cout << i << endl; 
} 
+0

もう少し文脈を与えるために、これは銀行プログラムの一部であると考えられています。ここでは、口座情報(名前、口座番号など)を格納する口座オブジェクトへのポインタの配列を使用します。当初、私は アカウント*のPTR [10] を宣言し、この PTR [i]のように、クラスアカウントのメンバ関数を(account.hが含まれている)にアクセスしようとした - > setacctnum(ACCT)。 が原因で、プログラムがクラッシュしました。なぜこれがうまくいかなかったのか分かりませんが、それが今のところです。 –

+0

'account * ptr [10]'を宣言すると、アカウントオブジェクトへの**初期化されていない**ポインタの配列が作成されます。だからこそあなたのプログラムはクラッシュしました。あなたは、ぶら下がっているポインタでメソッドを呼び出そうとしました。 'ptr [i] .setacctnum(acct);'( ' - ' 'の代わりに' .'に気付く)のような呼び出しでメンバ関数にアクセスすることができるでしょう。 'ptr [i]'はポインタではなくオブジェクトになっているからです)。本当にポインタが必要な場合は、 'std :: unique_ptr' – wasthishelpful

3

すべてnewは、各ポインタのポインタの配列、およびnewを持っている場合は、各インスタンスdeleteに必要があると思いdelete

でbalanacedする必要があります。

newオブジェクトの配列の場合は、配列全体をdelete []にすることができます。サイドポイントとして

、あなたのコードの代わりにptrを使用して(あなたは、の詳細は、単に必要に応じて、それが自動的に代わりptr[i] = new...の、サイズますstd::vector<account>を使用してpush_backの使用を検討して私たちに語っていない。

1

一般的に、あなたが作成し、各インスタンスを削除する必要があります。正確にはどのようにするかは少し異なりますが、簡単な経験則は

newの場合はdeleteを使用する必要があります。

new[]を使用するたびにdelete[]を使用する必要があります。

インスタンスを自動宣言から取得した場合、スタックフレームで破棄されるため、何もする必要はありません。しかし、あなたが作成した場合、あなたはそれを破壊する。あなたがnewを使用場合は他の人が指摘したように

1

あなたはdeleteが必要です。しかし、あなたの本当の問題は概念的です。 newdeleteが末梢であるという良い質問をします。

時間の99.5%を超える通常のデストラクタの使用は、コンパイラにそれらを自動的に呼び出させることです。 (0.5%の例外は難解である私たちは今ことを心配する必要はありません。)

このコードフラグメントを考えてみましょう:

int n = 5; 
    { 
    int m = 2; 
    ++m; 
    n *= m; 
    // The variable m is automatically destructed here. 
    } 
    // Here, n == 15. 

は、それがどのように動作するかを参照してください? mのデストラクタは、mの寿命が終了すると(mnewで作成されていないため)mがインスタンス化されたブロックの最後に発生すると、自動的に呼び出されます。

もちろん、mintなので、そのデストラクタは何もしません(または、好きな場合は、デストラクタがありません)。タイプaccountのように自分で定義する他のタイプは、デストラクタを持つことができます。デストラクタはです。というインスタンスが1つのオブジェクトに対して期限切れになると、その時点で1つのオブジェクトに対してが自動的に呼び出されます。

NEWので

をDELETE、何これはnewdeleteと関係があるのでしょうか?

私のコードでは、newを使用しませんでした。したがって、私のオブジェクトの寿命は、中括弧によって制御されていました。

コードフラグメントでは、newを使用しました。したがって、オブジェクトの寿命はdeleteの使用によって制御されます。

もちろん、deleteを忘れてしまったので、あなたのオブジェクトは決して破壊されませんでした(あなたのプログラム全体が終了した時を除いて)。

他の人は、現代のC++には、ほとんどの場合に使用すべき改良されたnewの代替が提供されていることに留意している人もいます。それらの答えを読むことができます。しかし、機械的には、普通のnewが何をしているのか、そしてdeleteとどのように対になるのかを理解することは、依然として非常に役立ちます。

DESTRUCTOR

の手動INVOCATIONデストラクタが手動で起動されている例はまれと進んでいるので、あなたはほぼ確実に、このことを心配する必要はありません。基本的には、オブジェクトが格納されているメモリを管理している場合(ほとんど実行しませんが、まれな例外があります)、コンパイラはいつ破壊するかを判断できません。一般的に難解な例については、thisを参照してください。

0

ポインタのみがそれらを削除したり、プログラムに

関連する問題