6
class Base
{
    virtual void foo() = 0;
    //~Base();     <-- No destructor!
};

明らかに、Base派生します。では、C++ は、コンパイラによって生成されたデストラクタBaseが仮想でなければならないと言っていますか?

ありがとう!

4

4 に答える 4

7

virtualいいえ、そのようにマークしない限り、デストラクタは存在しません。理由は単純です。呼び出しは、ポインターと参照の両方を介して仮想的に行うことができ、仮想的に呼び出しを行う方法とかどうかは、を使用してオブジェクトを作成するかどうかとは無関係ですnew。オブジェクトを作成しない場合は、オブジェクトを作成する必要がないため、仮想デストラクタは必要ありnewませdeleteん。

于 2011-08-12T14:56:07.947 に答える
2

そうではありません。これは、デストラクタが自動的に仮想化されないことの証明に近いです。

#include <iostream>

struct BaseBase {
    ~BaseBase() {
        std::cout << "~BaseBase\n";
    }
};

struct Base : BaseBase
{
    virtual void foo() = 0;
    //~Base();     <-- No destructor!
};

struct Derived : Base {
    void foo() { std::cout << "foo\n"; }
    ~Derived() {
        std::cout << "~Derived\n";
    }
};

int main() {
    Base *p = new Derived();
    delete p;
}

このプログラムは実際には未定義の動作をしますが、あなたの実装では "~Derived" が出力されないのではないかと強く疑っています。仮想デストラクタがある場合Base、未定義の動作はなく、「~Derived」と出力されます。

もちろん、実際には標準について何も証明していません。それを実行する実装は、結局のところ非準拠である可能性があります。しかし、いくつか試してみると、標準が何を言おうと、仮想デストラクタを指定する必要があることがわかります。

于 2011-08-12T15:01:23.630 に答える
1

クラスは仮想メンバーを持つことができ、派生することができ、仮想デストラクタがなくても割り当てnewおよび削除することさえできます。delete

違法 (UB) とは、デストラクタが仮想として宣言されていない場合に、delete ベースへのポインタを使用して派生インスタンスを破棄することです。

もちろん、クラスが派生することを意図している場合、仮想デストラクタを宣言しない理由はまったくありません。

于 2011-08-12T15:10:20.420 に答える
1

いいえ、dtor が仮想であることは保証されていません。

派生するように特別に設計されたクラスを宣言するときは、仮想 dtor を明示的に宣言することをお勧めします。通常、そうしないのは完全な設計上の欠陥です。実際、基本クラスから仮想 dtor を省略することが設計上の欠陥ではないケースは考えられません。

于 2011-08-12T14:58:02.473 に答える