【问题标题】:C++ - how to delete sub-classes in destructorC++ - 如何在析构函数中删除子类
【发布时间】:2020-04-03 05:38:05
【问题描述】:

这是一个类定义:

class Person {
private:
    char* name;
    int numChildren;
    Person** childrenList;
public:
    Person(char* name);
    ~Person();
};

Person::Person()构造函数中,会根据构造函数参数设置人名,然后为每个孩子创建Person对象,每个孩子可能还有其他孩子。假设一种情况,在我运行此代码后:Person* me = new Person("Alex");,将创建以下结构: 即如果me被创建,me的孩子也会被递归创建。

但我在 Person::~Person() 析构函数中遇到了问题。在析构函数中,它应该删除所有动态对象,包括名称和每个子对象。这是我的尝试:

Person::~Person() {
    for (int i = 0; i < numChildren; i++) {
        // go inside each child
    }
    delete[] this->name;
    delete[] childrenList;
}

但我不知道如何进入每个child,并且析构函数没有参数。

谁能给我一些提示?谢谢!

【问题讨论】:

  • 通常,答案是“不要自己分配内存,而是使用字符串和向量以及智能指针,它们会自动清理”。您是否需要(例如教授)使用新/删除?也就是说,如果您只是 delete 该循环中的每个孩子,它将调用该孩子的析构函数并启动您正在寻找的递归链。
  • @parktomatomi 很好,它来自家庭作业,我对其进行了一些更改,我不允许修改类定义,所以我必须使用 new/delete。删除第一个时有什么方法可以删除所有内容吗?
  • 你的构造函数是什么样的? (有时析构函数看起来像“反向”的构造函数。)
  • 你快到了。如果你在栈上声明了根 Person,析构函数会被自动调用。如果你用new 声明了堆上的根Person,那么当你delete 它时会调用析构函数。所以如果你删除第一个,它会调用你的析构函数。然后,如果析构函数在该循环中删除 childrenList 中的每个条目,它将为每个孩子调用析构函数,直到剩下的唯一指针为 NULL 或列表为空。
  • @parktomatomi 你能解释一下什么时候调用children析构函数吗?你的意思是如果我只是delete childrenList,每个children的析构函数都会被调用?

标签: c++ class destructor


【解决方案1】:

只是delete你之前的每个孩子delete[] childrenlist

Person::~Person()
{
    for (int i = 0; i < numChildren; i++) {
        delete childrenList[i];
    }
    delete[] childrenList;
    ...
}

【讨论】:

    【解决方案2】:

    当使用像Person** childrenList 这样的双指针时,你必须这样做来分配和删除它:

        unsigned len1 = 100;
        unsigned len2 = 100;
    
        //  childrenList is a pointer to a an array of pointers
        Person** childrenList = nullptr;
    
        // create an array with UNALLOCATED Person pointers, note the "*"
        childrenList = new  Person*[len1];          
    
        // allocate all the pointers in the the array
        for (size_t i1 = 0; i1 < len1; i1++)
            childrenList[i1] = new Person;
    
    
        // delete all the pointer in the array
        for (size_t i1 = 0; i1 < len1; i1++)
            if (childrenList[i1])
                delete childrenList[i1];        
    
        // delete the array itself
        delete[] childrenList;
    

    你可以把它放在你的析构函数中:

    Person::~Person()
    {
    // delete all the pointer in the array
            for (size_t i1 = 0; i1 < len1; i1++)
                if (childrenList[i1])
                    delete childrenList[i1];        
    
            // delete the list itself
            delete[] childrenList;
    
    }
    

    但是使用“2d”std::vector 可以更轻松地完成整个事情:

    vec<vec<Person>> childrenList;
    

    这样的二维向量有自己的语法,但它比“裸”指针/数组更容易且不易出错。- PS:我没有尝试编译或运行这个例子。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-09-09
      • 1970-01-01
      • 2014-03-13
      • 2014-12-10
      • 2012-08-11
      • 2018-09-12
      • 2014-12-30
      相关资源
      最近更新 更多