Если у нас нет виртуальных конструкторов, то почему у нас есть виртуальные деструкторы? Могут ли конструкторы также быть виртуальными?Нет виртуальных конструкторов, но виртуального деструктора
ответ
- В виртуальном конструкторе нет смысла - вы точно определяете тип , и это хорошо известно во время компиляции. Компилятор не нужен [и на самом деле не может, поскольку динамическая отправка основана на на информации, которая создается только после создания объекта]. Итак, виртуальных конструкторов нет.
- Виртуальные деструкторы важны для предотвращения утечек памяти, а - мониторинг системы. Предположим, у вас есть
A* a = new B;
[B
наследует отA
], а позже выdelete a;
- компилятор не имеет возможности знаяa
являетсяB
[в общем случае], и будет вызыватьA
«s деструктор - если бы не было виртуальный, и вы можете получить утечку памяти, или другие ошибки. - Использование виртуального деструктора - вы убедитесь, что
B
«s деструктор вызывается, так какB
объект разрушается.
Виртуальные деструкторы необходимы, потому что во время разрушения, вы не всегда знаете, какой тип вы имеете дело с:
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», который действительно знает.)
#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) вызовет деструктор базы но фактический девиз - удалить производный класс. поэтому нам нужно, чтобы деструктор был виртуальным по своей природе.
Возможный дубликат [Почему у нас нет виртуального конструктора в C++?] (Http://stackoverflow.com/questions/733360/why-do-we-not-have-a-virtual-constructor-in- c) –
@TomaszNurkiewicz: Я думаю, что вопрос скорее, почему у нас есть виртуальные деструкторы в C++? –