0

ファンキーなタイトルですが、正直なところ、これ以上の人物は思いつきませんでした。申し訳ありません :(

ポインターを試しているときに、これに遭遇したので、理解するのに助けが必要です。基本的に、オブジェクトへのポインターのベクトルを作成します。ベクター内のポインターを削除すると、元のオブジェクトも削除されると思います。それらはまったく同じですよね?

動的に割り当てられた配列を作成し、配列の要素の半分へのポインターをポインターのベクトルに入れます。クラス testDestructor のすべてのオブジェクトが作成された「順序」を認識する方法の各ステップでは、静的整数を介して増分番号がすべて割り当てられます。

次に、ベクトル内のすべてのポインターを pop_back して削除します。ベクトルクラスによって削除されるかどうかを確認したかったので pop_back のみを使用しますが、明らかにそうではありませんが、そこに何かが欠けている場合はidkします。重要なのは、削除することです。

さて、私が期待しているのは、これにより配列の対応する要素も削除されることです。ベクトルと配列要素がメモリ内の同じ場所を指しているため、これが起こるべきです。つまり、デストラクタを呼び出す必要があります。

そのため、配列を削除すると、5 つの要素のみが削除されるか、実行時エラーが発生することが予想されます (既に削除されているポインターを削除しようとしたときに、以前にこの問題が発生したことがありますが、別のシナリオ idk)。つまり、デストラクタだけが 5 回しか呼び出されないことを期待しています。

しかし、それは起こりません。コンストラクタは 10 回呼び出されますが、デストラクタは 15 回呼び出されます。私は何が欠けていますか?コンストラクターがありませんか (デフォルト コンストラクターとコピー コンストラクターについてしか知りませんが、他にもあります)、それとも何か他のものですか? 私の考えでは、デストラクタがなくなるとオブジェクトがなくなるからです。

コードが多すぎる場合は申し訳ありません:

testDestructor.h:

#ifndef TESTDESTRUCTOR_H
#define TESTDESTRUCTOR_H

class testDestructor
{
public:
   testDestructor();
   testDestructor(const testDestructor &);
   ~testDestructor();

   static int maxTest;
   int test;
};

#endif

testDestructor.cpp:

#include "testDestructor.h"
#include <iostream>

using namespace std;

int testDestructor::maxTest = 0;

testDestructor::testDestructor()
{
   test = maxTest++;
   cout << "testDestructor nr " << test << " created successfully\n";
}

testDestructor::testDestructor(const testDestructor &destructorToCopy)
{
   test = maxTest++;
   cout<< "testDestructor nr " << test << " created successfully (using the copy constructor\n";
}
testDestructor::~testDestructor()
{
  //maxTest--;
   cout << "testDestructor " << test << " destroyed successfully\n";
}

main.cpp:

#include <iostream>
#include "testDestructor.h"
#include <vector>
using namespace std;

int main()
{
   cout << "   creating pointer array:\n\n";
   testDestructor *testPtr = new testDestructor[10];

   cout << "   intitiating vector\n\n";
   vector<testDestructor*> testVct;


   for (int i = 0; i < 5; i++)
   {

      cout << "   pushing back vector " << i << ":\n";
      testVct.push_back(testPtr + i);
      cout << "testDestructor " << testVct[i]->test << " pushed back\n";
   }
   cout << "\n";

   for (int i = 4; i >= 0; i--)
   {
      cout << "   popping back vector " << i << ":\n";
      cout << "testDestructor " << testVct[i]->test << " popped back\n";

      delete testVct[i];
      testVct.pop_back();

   }
   cout << "\n";

   cout << "   deleting pointer array\n\n";
   delete [] testPtr;
}
4

5 に答える 5

2

ベクター内のポインターを削除すると、元のオブジェクトも削除されると思います。それらはまったく同じですよね?

いいえ、それらは同じではありません。「ポインターを削除する」という用語は、C++ のポインターに関するいくつかの基本的なことを読み直す必要があることを意味します。

newものを作成し、作成したものへのポインターを返します。delete物を破壊し、破壊する物へのポインターが渡されます。ポインタは変更されていません - 削除後に有用な場所を指していないだけです。

あなたがやろうとしているのはdelete、で作成されたオブジェクトの配列内の個々のオブジェクトですnew[]。それは単に行うことはできません。delete[] でのみロット全体を削除できます。個別に削除可能なオブジェクトが必要な場合は、std::vector<TestDestructor>.

于 2012-07-18T23:16:56.823 に答える
1

演算子delete[]は、配列自体を削除する前に、配列内の項目のデストラクタを呼び出します。配列内の項目の一部を手動で削除したい場合は、NULL後で配列インデックス値を設定する必要があります。同じオブジェクトでデストラクタを 2 回呼び出すことは未定義の動作であり、うまくいけばうまくいきません。

于 2012-07-18T23:05:47.443 に答える
1

ここでの問題は、 の最初の 5 つのインスタンスがtestDestructor2 回削除さdelete testVct[i]れることdelete [] testPtr;です。

最初deleteは間違っています。

オブジェクトはによって所有されているため、それらの破棄はのイオンによってtestVctのみ実行できます。によって割り当てられた場合にのみ、オブジェクトを個別化できます。delete[]testVctdeletenew

于 2012-07-18T22:59:42.163 に答える
0

まず、変数宣言を見てみましょう。

testDestructor *testPtr = new testDestructor[10];
vector<testDestructor*> testVct;

これは、testPtrがtestDestructor型のオブジェクトへのポインターであり、testVctがtestDestructor型のオブジェクトへのポインターのベクトルであることを示しています。

さらに、new演算子を使用してtestDestructorオブジェクトの配列を割り当て、testPtrの最初の要素のアドレスを割り当てます。これで、testPtrをtestDestructorオブジェクトの配列として使用できます。

個々のtestDestructorオブジェクトにメモリを割り当てていないことに注意してください。これは、配列内のオブジェクトへのポインタを削除すると、未定義の動作が発生することを意味します。一方、testPtrでdelete []を使用して配列の割り当てを解除することは、許可されています。

ここでの一般的なルールは、すべてのdeleteまたはdelete []に​​一致するnewまたはnew[]が必要であり、その逆も同様です。

于 2012-07-18T23:21:30.130 に答える
0

初め

私のテストでは、このプログラムは 'delete testVct[i];' でコア ダンプします。

私のg ++​​バージョンは4.1.6です

たぶん、testPtrを初期化できます:

testDestructor *testPtr[10];
for(int i=0;i<10;i++)
    testPtr[i] = new testDestructor;

2番

ポインタを 2 回削除します。1) delete testVct[i]; 2) [] testPtr を削除します。

于 2012-07-19T06:08:10.817 に答える