2012-03-29 4 views
2

Если у нас нет виртуальных конструкторов, то почему у нас есть виртуальные деструкторы? Могут ли конструкторы также быть виртуальными?Нет виртуальных конструкторов, но виртуального деструктора

+0

Возможный дубликат [Почему у нас нет виртуального конструктора в C++?] (Http://stackoverflow.com/questions/733360/why-do-we-not-have-a-virtual-constructor-in- c) –

+1

@TomaszNurkiewicz: Я думаю, что вопрос скорее, почему у нас есть виртуальные деструкторы в C++? –

ответ

16
  • В виртуальном конструкторе нет смысла - вы точно определяете тип , и это хорошо известно во время компиляции. Компилятор не нужен [и на самом деле не может, поскольку динамическая отправка основана на на информации, которая создается только после создания объекта]. Итак, виртуальных конструкторов нет.
  • Виртуальные деструкторы важны для предотвращения утечек памяти, а - мониторинг системы. Предположим, у вас есть A* a = new B; [B наследует от A], а позже вы delete a; - компилятор не имеет возможности зная a является B [в общем случае], и будет вызывать A «s деструктор - если бы не было виртуальный, и вы можете получить утечку памяти, или другие ошибки.
  • Использование виртуального деструктора - вы убедитесь, что B «s деструктор вызывается, так как B объект разрушается.
+0

Я не понял первый момент. Можете ли вы его разработать, пожалуйста. – devsda

+1

@jhamb: Когда вы вызываете конструктор - это что-то вроде 'new MyClass;'. * Динамический тип * и * статический тип * созданного объекта - это точно то же самое, настоящий конкретный объект. – amit

2

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

Base *make_me_an_object() 
{ 
    if (the_moon_is_full()) 
     return new Derived(); 
    else 
     return new Base(); 
} 

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

В delete в выше програмы main не знает, является ли его p указывает на Base или его Derived объекта, но если Base деструктор virtual (как это должно быть), то можно использовать delete*p «s vtable, чтобы найти правильный деструктор.

В отличие от этого, во время строительства вы всегда знаете, какой объект вы создаете. (И в случае, если вы этого не сделаете, то вы можете создать фабрику или «virtual constructor», который действительно знает.)

0
#include<iostream> 
using namespace std; 
class base { 
    protected: 
    int a; 
}; 
class derived : public base { 

}; 
int main() { 
    base * pointer_of_base = new derived; 
    delete pointer_of_base; // this will delete the base calss not the derived 

} 

Конструкторы вызываются на один раз, когда мы создаем объект класса таким образом, когда мы наследуем конструкторы базового класса звонят только один раз, поэтому нет необходимости быть виртуальными.

Но когда мы обращаемся к производному классу из указателя базового класса, если мы хотим удалить объект производного класса, мы удалим его указателем базового класса, но delete (pointer_of_base) вызовет деструктор базы но фактический девиз - удалить производный класс. поэтому нам нужно, чтобы деструктор был виртуальным по своей природе.