1
Class Shape {
    virtual Shape() = 0;
    virtual ~Shape() = 0;
}

Class Circle : Public Shape {
    Circle();
    ~Circle();
    // Something ...
}

int main () {
Shape* s = new Circle();
delete s;
}

Circleのコンストラクターを呼び出していますか?Shape のコンストラクトの別の名前でもいいですか?s を削除するとき、Circle のデストラクタを呼び出していますか?

4

3 に答える 3

1

C++ では、コンストラクターを仮想にすることはできません。

あなたが提供したコードは有効な C++ ではありません。

修正されたコードは次のとおりです。ここで実行できます: http://codepad.org/2fDc4S3e プログラムの出力は、すべての質問に答えるはずです。コードを試して、その他の質問に答えることをお勧めします。

class Shape {
public:
    virtual ~Shape() = 0;
};

Shape::~Shape() { std::cout << "Shape dtor called" << std::endl;} // Since you declared the destructor pure virtual you must define it

class Circle : public Shape {
public:
    Circle() { std::cout << "Circle ctor called." << std::endl; }
    ~Circle() { std::cout << "Circle dtor called." << std::endl; }
    // Something ...
};

int main () 
{
  Shape* s = new Circle(); // This will call the constructor of Circle
  delete s; // This will call the destructor of Circle and then the dtor Shape.
  return 0;
}
于 2012-08-26T06:25:05.943 に答える
0

はい、Circle の dtor が呼び出されます。

  • Shape の dtor は仮想であるため、それを継承するすべてのクラスは仮想 dtor を持ちます。
  • これは、dtor が直接呼び出されるのではなく、v-table を介して呼び出されることを意味します。「s を削除」すると、s.dtor() が呼び出され、v-table 内の正しい項目 (Circle の dtor) が呼び出されます。
于 2012-08-26T06:24:20.297 に答える
0

コンストラクターを仮想にすることはできません。

class Shape {
    virtual ~Shape() = 0;
};

class Circle : public Shape {
    Circle() {};
    ~Circle() {};
};

int main() {
    Shape *s = new Circle();
    delete s;
}

はい、new Circle()Circle のコンストラクターを呼び出します。これは、式がnew <type><optional initializer>十分なメモリを割り当ててから、適切なコンストラクタ (または非クラス型のその他の初期化) を呼び出して初期化するためです。最も派生した型を明示的に述べているため、これについて仮想である必要はありません。

の結果はnew Circle()Circle へのポインターです。この型を Shape へのポインター型の変数に割り当てるには、暗黙的な変換が必要です。変換の結果は、Circle の基本 Shape サブオブジェクトへのポインターです。Shape は仮想ベースではなく、通常のベース オブジェクトであり、Circle 内の位置は静的に知られているためです。

delete sCircle デストラクタを呼び出します。これは仮想ディスパッチを使用します。コンパイラは、Shape を削除していることを認識しており、Shape のデストラクタは仮想であるため、適切なデストラクタ ( ) を検索して~Circle()呼び出します。Shape のデストラクタが仮想的でない (実際にどこかに定義がある) 場合、これは行われず、Circle オブジェクトではなく Shape オブジェクトのみが破棄され、割り当て解除が正しく行われない可能性があります。動作は未定義です。

于 2012-08-26T06:29:15.540 に答える