2013-03-08 4 views
0

пожалуйста, пройти через мой код ниже:Destructor понятие в C++

#include "stdafx.h" 
#include <iostream> 
#include <conio.h> 
using namespace std; 

class ClassA 
{ 
    protected: 
    int width, height; 

    public: 
    void set_values(int x, int y) 
    { 
     width = x; 
     height = y; 
    } 
    virtual int area() 
    { 
     return 100; 
    } 
    ~ClassA() 
    { 
     cout << "base class destructor called" << endl; 

    } 
}; 

class ClassB : public ClassA 
{ 
    public : 
int area() 
{ 
    return (width * height); 
} 
~ClassB() 
{ 
    cout << "derived class destructor called" << endl; 
} 
}; 
int main() 
{ 
    ClassA *Ptr = new ClassB; 
    Ptr->set_values(10, 20); 
    cout << Ptr->area() << endl; 
    delete Ptr; 
    return 0; 
} 

В приведенном выше коде указатель содержит адрес объекта производного класса, так он должен вызывать производный класс деструктор вместе с деструктор базового класса, когда я удалить указатель, но почему он вызывает только деструктор базового класса. если я сделал деструктор базового класса как виртуальный, то он вызывает как производный класс, так и деструктор базового класса, почему ?. и в случае виртуальных функций, как базовый, так и производный класс имеет одно и то же имя функции, поэтому компилятор разрешает ту, которая наиболее выведена в производном классе, но здесь деструктор не будет иметь того же имени, а затем, как компилятор решает, какой из них нужно вызвать во время бега time.please объяснить мне, как

ответ

0

это на самом деле неопределенное поведение потому ~ClassA() не virtual, так что все может случиться.

ClassA *Ptr = new ClassB; 
///.... 
delete Ptr; 
+0

обязательно прочтите мое объяснение .. – nagaradderKantesh

2

Потому что ваш деструктор базового класса должен быть virtual.

0

Вы должны пометить своих деструкторов как виртуальные. В противном случае компилятор не знает, чтобы вызвать наиболее производный деструктор.

virtual ~ClassA() 
{ 
    cout << "base class destructor called" << endl; 

} 
+0

обязательно прочтите мой информация .. – nagaradderKantesh

3

Вы должны сделать деструктор базового класса virtual для того, чтобы полиморфное разрушения работать должным образом:

class ClassA 
{ 
    // ... 
    virtual ~ClassA() 
// ^^^^^^^ 
// Add this! 
    { 
     cout << "base class destructor called" << endl; 
    } 
}; 

Если вы не сделаете этого, вы получаете Неопределенное поведение при выполнении delete Ptr.

Если я сделал деструктор базового класса виртуальным, то он вызывает как производный класс, так и деструктор базового класса, почему?

Это часть обычной последовательности уничтожения объекта. Когда вы уничтожаете объект, деструктор класса этого объекта вызывается первым, затем деструкторы всех нестатических членов класса этого объекта (в обратном порядке объявления), , затем деструкторы всех его базовых классов.

Таким образом, виртуальная диспетчеризация выполняется правильно (если вы, конечно, сделаете свой деструктор базового класса virtual), в том смысле, что первый деструктор, который вызывается, является деструктором фактического типа времени выполнения вашего объекта (ClassB). После этого вызывается деструктор базового класса ClassA, а также часть процесса нормального уничтожения.

но здесь деструктор не будет иметь такое же имя, то, как компилятор решает, какой из них должен вызывать во время выполнения

деструкторы являются специальные функции-члены. Каждый класс может иметь только один деструктор, поэтому их имя (которое должно быть идентично имени класса, с предшествующим символом ~) не имеет значения. Компилятор знает, какая функция является деструктором.

+0

обязательно прочтите пожалуйста. – nagaradderKantesh

+0

@ nagaradderKantesh: Я обновил свой ответ. –

Смежные вопросы