0

下面的问题不是很常见,所以我在网上找不到任何可能有帮助的东西:

我有class parent,它必须有默认的构造函数和析构函数,我不应该定义关于这两个成员的任何内容。

我需要控制ptr破坏,只有在它没有被引用时才必须被破坏,这由counterin控制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;
}

问题是在parent 的默认析构函数中this line被调用并且确实没有被正确地破坏。ptr = NULLptr

有没有办法通过这些限制跳过 ~parent 的调用?

我也尝试删除继承,并有一个parentin的实例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就OK了。然后我想析构函数被调用并且ptr似乎是NULL.

因此,上面将打印:

iterating
ptr is OK
in child
ptr is NULL
Segmentation fault

修改后有什么解释吗?

非常感谢大家!

4

3 回答 3

2

问题是在这一行中调用了父级的默认析构函数

不。

并且 ptr = NULL,

和不。

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

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

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

于 2013-02-01T17:43:25.053 回答
1

想到两件事:

  1. 您可以轻松检查if(ptr) ...[或者if (this->ptr)如果您愿意]。
  2. 这似乎相当“错误”。不调用基类析构函数绝对不是正常类行为的一部分,并且会让我认为类层次结构是错误的。

所以,总而言之,当你“需要”这样做时,你可能做错了什么。想想你的类如何交互,并解决基本问题。

于 2013-02-01T16:46:34.457 回答
0

delete如果父级的析构函数不是虚拟的,则通过派生指针访问对象是未定义的行为,因此此代码表现出未定义的行为。

无论如何,如果父级没有定义析构函数,那么你为什么担心不调用它呢?

于 2013-02-01T16:42:20.543 回答