4

私は次の例を試しています:

class base // base class
{
public:
    std::list<base*> values;
    base(){}
    void initialize(base *b) {
        values.push_front(b);
    }
    virtual ~base()
    {
        values.clear();
        cout<<"base called"<<endl;
    }
};

class derived : public base // derived class
{
public:
    ~derived(){
        cout<<"derived called"<<endl;
    }

};

int main()
{
    derived *d = new derived;
    base *b = new base;
    b->initialize(static_cast<base *>(d)); /* filling list */
    delete b;
    return 0;
}

Q.1) 実行している基本クラスのデストラクタのように、派生クラスのデストラクタが呼び出されないのはなぜvalues.clear()ですか?

Q.2) 基本クラスのデストラクタが仮想の場合、派生クラスのデストラクタの定義は必要ですか?

4

4 に答える 4

7

Q1. タイプのオブジェクトを削除していないためですderiveddelete b;を削除するだけですbase。も呼び出す必要がありますdelete d;

また、メモリ管理を担当するオブジェクトを指定する必要があります。あなたのデザインはエラーを起こしやすいです。あいまいさを防ぐために、スマート ポインターを使用することをお勧めします。また、期待どおりに動作させるには、デストラクタを次のようにする必要があります

virtual ~base()
{
    for ( int i = 0 ; i < values.size() ; i++ )
        delete values[i];
    values.clear();
    cout<<"base called"<<endl;
}

もちろん、このアプローチではdelete d;、あなたのmain.

Q2. いいえ、定義は必要ありません。

于 2012-04-23T10:59:01.417 に答える
4

私が実行している基本クラスのデストラクタのように、派生クラスのデストラクタが呼び出されないのはなぜですかvalues.clear();

values.clear()このリストからすべてのポインタを削除します。指しているオブジェクトは削除されません。これは非常に危険です。なぜなら、リストはその存続期間に責任があるのか​​、または別の場所で管理されているオブジェクトを参照するために使用されているだけなのかを知る方法がないからです。

リストにオブジェクトを所有させたい場合は、オブジェクトを削除するときに自分で削除するか、 などのスマート ポインターを保存する必要がありますstd::unique_ptr<base>。コンパイラが新しいスマート ポインタをサポートしていない場合は、Boost のPointer Containerライブラリが役立つことがあります。

派生クラスのデストラクタ定義が必要ですか。基本クラスのデストラクタが仮想の場合。

派生クラスにクリーンアップが必要なものがある場合にのみ必要です。何もすることがなければ、空のものを定義する必要はありません。

于 2012-04-23T11:00:25.943 に答える
1

実際にはそうではないdelete dので、もちろんデストラクタは呼び出されていません。d を (derived dの代わりにderived *d = new derived) 静的に割り当てられるようにするか、 を呼び出しますdelete d

派生クラスでデストラクタを宣言しない場合、デフォルトのデストラクタが作成されます。基本クラスのデストラクタは引き続き呼び出されます。FAQ (11.12) を参照してください。また、基本クラスのデストラクタは仮想であるため、派生クラスのデストラクタは自動的に仮想になることにも注意してください (定義するかどうかに関係なく) 。FAQ (20.7) を参照してください。

于 2012-04-23T10:58:50.047 に答える
0

派生クラスのデストラクタを呼び出す必要があるのはなぜだと思いますか? base を削除するだけで、それは基本クラスのインスタンスです。

いいえ、デストラクタの定義は必要ありません。省略してもかまいません。

于 2012-04-23T11:00:00.427 に答える