以下问题不是很常见,因此我在网上找不到任何有帮助的内容:

我有class parent,它必须具有默认的构造函数和析构函数,我不应该为这两个成员定义任何东西。

我需要控制ptr销毁,只有在未引用它的情况下,销毁它才必须销毁,而销毁是由counter中的someclass控制的。

class parent {
public:
   someclass * ptr;
}
class child: public parent {

   ~child() {                           //<-- this line
      cout<<"in ~child!"<<endl;
      if(this->ptr == NULL)  cout<<"ptr is NULL"<<endl;
      this->ptr->delete_reference();    //<-- here ptr = NULL
    }

    someclass* get_ptr() {
       return this->ptr;
    }
}

class someclass {
  void delete_reference() {
    counter--;
    if(counter == 0)   delete this;
}


问题在于,在this line中调用了父级的默认析构函数,并且执行了ptr = NULL,因此,ptr没有被正确地析构。

有没有办法在这些限制下跳过〜parent的电话?

我还尝试删除继承,并在parent中具有child的实例,但是发生相同的事情,再次调用了父级的析构函数。

此外,我需要ptr中的parent,因为有更多的子类,他们需要共享此信息。

谢谢!

编辑:
据我所知,我在这里遇到了问题...问题是ptr如何变为NULL。
只要我混淆了析构函数调用的顺序,那么问题就不在this line中。

void function() {
  child ch1;
  for(int i = 0; i<1; i++) {
    cout<<iterating<<endl;
    do_some_work(ch1);
  }
  if(ch1->get_ptr() != NULL) cout<<"ptr is OK"<<endl;

  return;
  //Here is the destructor ~child called (?)
}

int main() {
  function();

}


上面的调用是我使用child的方式。在do_some_work内部,实际上有很多工作很难在这里描述。

关键是do_some_work完成后,ptr可以。然后,我假设调用了析构函数,并且ptr似乎是NULL

因此,上面将打印:

iterating
ptr is OK
in child
ptr is NULL
Segmentation fault


修改后有什么解释吗?

非常感谢大家!

最佳答案

问题是在这一行中,父级的默认析构函数被称为
  


没有。


  
    并且ptr = NULL,
  


和不。

首先,父级的析构函数(默认或其他)在子级之后而不是之前被调用。

其次,父级的默认析构函数可能未将ptr设置为NULL。它可能根本不碰ptr。 (我说“大概”,因为没有办法知道。在父析构函数返回后完全引用ptr是未定义的行为。)

我建议您得出错误的结论。请发布简短的完整程序,以演示您的问题,我们可以帮助您得出正确的结论。

09-07 03:36