0

以下の問題はあまり一般的ではないため、オンラインで役立つものは見つかりません。

私はclass parent、デフォルトのコンストラクタとデストラクタを持っている必要がありますが、これら2つのメンバーについて何も定義することは想定されていません。

破壊を制御する必要があります。ptr参照されていない場合にのみ破壊する必要があります。これは、で制御さcountersomeclassます。

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の呼び出しをスキップする方法はありますか?

また、継承を削除しようとし、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を実行し、

そして、いいえ。

まず、親のデストラクタ(デフォルトまたはそれ以外)は、子の前ではなく、子のに呼び出されます。

ptr次に、親のデフォルトのデストラクタはおそらくに設定されていませんNULL。おそらくまったく触れないでしょうptr。(知る方法がないので、「おそらく」と言います。ptr親デストラクタが戻った後に参照することは、未定義の動作です。)

私はあなたが間違った結論に達したと提案します。あなたの問題を実証する短い完全なプログラムを投稿してください、そして私たちはあなたが正しい結論に到達するのを手伝うことができます。

于 2013-02-01T17:43:25.053 に答える
1

2つのことが頭に浮かびます。

  1. if(ptr) ...[または必要に応じて]簡単に確認できif (this->ptr)ます。
  2. これはかなり「間違っている」ように見えます。基本クラスのデストラクタを呼び出さないことは、間違いなく通常のクラスの動作の一部ではなく、クラス階層が間違っていると思わせます。

したがって、要約すると、これを「必要」とするときに、おそらく何か間違ったことをしていることになります。クラスがどのように相互作用するかを考え、根本的な問題を修正します。

于 2013-02-01T16:46:34.457 に答える
0

delete親のデストラクタが仮想でない場合、派生ポインタを介してオブジェクトを実行することは未定義の動作であるため、このコードは未定義の動作を示します。

とにかく、親にデストラクタが定義されていない場合、なぜそれを呼び出さないことを心配しているのですか?

于 2013-02-01T16:42:20.543 に答える