0

読み取り専用と見なされる基本クラスがあり、その仮想デストラクターでは何もしません。次に、その Base クラスを書き込み可能な Derived クラスに派生させ、そのデストラクタで Base メンバーを削除します。

class Base
{
    virtual ~Base() {}
    void* Data;
}
class Derive : public virtual Base
{
    virtual ~Derive() { delete Data; }
}

Base クラスを参照として受け取る Function に Deriv インスタンスを渡す場合、上記の構文的に正しくないコードは無視します。

void Function(const Base& base)
{
   ...
}

...
Derive der = Derive();
...
Function(der);

Derived デストラクタは Function スコープの最後で呼び出されますか? 答えを見つけるのに適切なキーワードを探すのに苦労したので、以前に尋ねられた場合は申し訳ありません. 私は、C++ が参照を扱う可能性のある型ではなく、それらが何であるかについて参照を扱うと仮定していますが、私は間違っている可能性があります。

4

2 に答える 2

3

いいえ、そうではありません。オブジェクトがスコープから外れることはないからです。スコープ外になり、への呼び出し後に自動的に破棄されFunctionます。

{
  Derive der = Derive();
  //...
  Function(der);
  //...
  //der still alive here
} //der is destroyed here, all destructors are called correctly

パラメータを参照ではなくで渡す場合:

void Function(Base base)
{
   ...
}

オブジェクトはスライスされます。内部で作成されたコピーは(ではなく)Function型のオブジェクトであるため、関数の終了時にデストラクタのみが呼び出されます。BaseDeriveBase

于 2012-10-09T14:12:02.893 に答える
0

Derived デストラクタは Function スコープの最後で呼び出されますか?

いいえ。 Derived デストラクタは、オブジェクトへの参照ではなく、オブジェクト自体がスコープ外になったときに呼び出されます。参照はオブジェクトではありません。ただの別名です。または、参照を、null にすることも、再割り当てすることもできず、 ..ではなくメンバーへのアクセスに使用するポインターと考えてください->。それ以外は、単なるポインターです。関数にポインターを渡す場合、関数の最後でポインターがスコープ外になるからといって、ポイント先のオブジェクトがスコープ外になるわけではありません。同じことが参照にも当てはまります。

あなたのデザインは少しファンキーです。いくつかの質問:

  • classのそのvoid*データ メンバーはどうなっていますBaseか?
  • なぜvoid*ポインタ?それはC++ではなくCの匂いです。
  • クラス内のメンバー関数はBaseそのデータ メンバーを使用していますか?
    • そうでない場合、なぜそのデータ メンバーはクラスの一部なのですか?
  • これは、少し疑わしいと~Derive()いうよりも、これを削除します。~Base()このデザインの背後にある理論的根拠は何ですか?
于 2012-10-09T14:32:40.617 に答える