已经被破坏的一系列物体上的破坏者

Destructor on a Array of objects, that were already destructed

本文关键字:破坏者 一系列      更新时间:2023-10-16

我对C 中的对象有些新,我有以下简化的问题:

我想创建一系列对象,这些对象已经由类的限制器初始化。

因此:

int main() {
 Test A(1);
 Test B(2);
 Test C(3);
 Test TestArray[3]={A,B,C};
 /*
  Code that both uses A,B,C directly and TestArray
 */
 return 0;
}

重要的是,Test类动态分配其值。因此,破坏者应删除此分配的内存。

因此:

class Test {
    int *PointerToDynMem;
public:
    Test(int);
    ~Test();
};
Test::Test(int a){
    PointerToDynMem=new int(a);
}
Test::~Test(){
    delete PointerToDynMem;
}

我认为会发生什么是程序结束时ABC脱离范围并致电驱动器。但是,似乎当TestArray脱离范围时,它也称为破坏者,但是ABC已经被划分为SOO。错误。

我总是像整数这样的普通类型对象进行编码,在这里,它从来没有给我任何问题。看来我需要更改某些东西,但不知道是如何确切的,因为我想分别使我们的对象和它们的数组。

我感到困惑的是,为什么数组应该称呼该驱动器,因为它基本上是指向第一个元素的指针,因此不是真正超出范围的对象。

TestArray[3]={A,B,C};将使用默认复制构造器复制由A,B和C持有的int*。为了解决这个问题,请创建所有将为您默默创建的构造函数和运营商。阅读三/五/零的规则。

class Test {
    int *PointerToDynMem;
public:
    Test(int);
    Test(const Test&);            // implement this
    Test(Test&&);                 // implement this
    Test& operator=(const Test&); // implement this
    Test& operator=(Test&&);      // implement this
    ~Test();
};

我感到困惑的是为什么数组应该称呼该灾难,因为它基本上是指向第一个元素的指针,因此不是真正超出范围的对象。

数组是不是指针。如果是的话,我们只会有指针。数组名称可以并且确实会腐烂到指向数组中第一个元素的指针(这真的很烦人),但这不是指针。它是一个将N对象存储在连续的内存中的对象,该大小信息是其类型的一部分。这意味着int[5]int[6]的类型不同。

这里发生的是

Test TestArray[3]={A,B,C};

创建一个三个Test的数组,然后复制从初始化器{A,B,C}中的数组中初始化每个Test对象。因此,当main结束时,TestArray被销毁,将每个元素的击路仪调用。然后以该顺序破坏的CBA

这对您来说是一个问题,因为您只需使用默认复制构造函数。这意味着数组中的每个对象都有一个由其初始化的对象点的副本,并且指向相同的内存。因此,当数组被破坏时,delete在所有成员指针上都被调用,然后将CBA试图再次删除相同的内存,这是未定义的行为。

您需要做的是遵循三个规则规则并创建特殊成员函数,以使您的课程正确复制,或者您可以以智能指针/ std::vector的形式使用RAII,然后让他们为您处理所有这些您可以使用零的规则

对于该代码,您需要添加复制构造函数(以及operator =等

Test::Test(const Test & t) {
  PointerToDynMem=new int(*t.PointerToDynMem);
}

其他您的int*共享(TestArray[0].PointerToDynMemA.PointerToDynMemTestArray[1].PointerToDynMemB.PointerToDynMemTestArray[2].PointerToDynMem是CC_32),并删除了2次