构造函数,析构函数和指针(以及向量和数组以及删除和那些)

时间:2012-07-18 22:54:35

标签: c++ pointers constructor destructor

时髦的头衔,但说实话,我想不出更好的人,对不起:(

在尝试使用指针时,我遇到了这个问题,我需要帮助理解它。基本上,我创建了一个指向对象的指针的向量。当删除向量中的指针时,我希望删除原始的ovject。他们是同一个没有?

这就是我认为我在后面的代码中创建一个动态分配的数组,然后我将指针放在一个指针向量中的数组的一半元素。类testDestructor的每个对象知道创建它的“顺序”的每一步,都会通过静态整数分配一个递增的数字。

然后我pop_back并删除向量中的所有指针。我只使用pop_back,因为我想看看它们是否被矢量类删除了,显然他们没有删除,但是如果我在那里遗漏了某些内容,那就是idk。重要的是我删除它。

现在,我期望发生的是,这也会删除数组的相应元素。应该发生这种情况,因为向量和数组元素指向内存中的相同位置。即,应该调用析构函数。

所以当我然后删除数组时,我希望只有5个元素被删除,或者发生运行时错误(我在尝试删除已经删除的指针之前就已经发生了这种情况,但是可能是一个不同的场景idk)。也就是说,我希望只有五次调用析构函数。

但是,这不是发生的事情。构造函数被调用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;
}

5 个答案:

答案 0 :(得分:2)

  

当删除向量中的指针时,我期待原始指针   也可以删除。他们是同一个没有?

不,它们不一样,你的术语“删除指针”意味着你需要重新阅读一些关于C ++指针的基本内容。

new创建东西,并返回指向它创建的内容的指针。 delete摧毁事物并传递指向要销毁的东西的指针。指针没有改变 - 它只是在删除后没有指向任何有用的地方。

您要做的是delete使用new[]创建的对象数组中的单个对象。这根本无法做到。您只能使用delete []删除整批。如果您想拥有可单独删除的对象,请使用std::vector<TestDestructor>

答案 1 :(得分:1)

此处的问题是,testDestructor的前五个实例会被删除两次:一次是delete testVct[i],另一次是delete [] testPtr;

第一个delete错误。

对象由testVct 拥有,因此只能通过delete[]的{​​{1}}来执行它们的破坏。只有testVct分配单个对象时才能delete个。{/ p>

答案 2 :(得分:1)

运算符delete[]将在删除数组本身之前调用数组中项目的析构函数。如果您希望手动删除阵列中的某些项目,则需要在之后将其数组索引值设置为NULL。在同一个对象上调用析构函数两次是未定义的行为,并且希望能够为你做坏事。

答案 3 :(得分:0)

首先,让我们看看你的变量声明:

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

这表示testPtr是指向testDestructor类型的对象的指针,testVct是指向testDestructor类型的对象的指针的向量。

此外,您使用new运算符分配一组testDestructor对象,并在testPtr中分配第一个元素的地址。现在testPtr可以用作testDestructor 对象的数组。

请注意,您尚未为任何单个testDestructor对象分配内存。这意味着您删除任何指向数组中对象的指针都将导致未定义的行为。另一方面,允许在testPtr上使用delete []来解除分配数组。

这里的一般规则是每个删除或删除[]必须匹配新的或新的[],反之亦然。

答案 4 :(得分:0)

第一

在我的测试中,该程序将核心转储到删除testVct [i];&#39;

我的g ++版本是4.1.6

也许你可以初始化testPtr:

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

第二

你删除指针两次 1)删除testVct [i]; 2)删除[] testPtr;