Нет виртуальных конструкторов, но виртуальный деструктор - PullRequest
3 голосов
/ 29 марта 2012

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

Ответы [ 3 ]

21 голосов
/ 29 марта 2012
  • Нет смысла в виртуальном конструкторе - вы объявляете, что именно Тип создан, и он хорошо известен во время компиляции. Компилятор не нужно [и фактически не может, так как динамическая отправка основана на информацию, которая создается только после создания объекта]. Так что нет виртуальных конструкторов .
  • Виртуальные деструкторы важны для предотвращения утечек памяти, и контролировать систему. Предположим, у вас есть A* a = new B; [B наследует от A], а вы позже delete a; - компилятор не имеет возможности знание a является B [в общем случае] и вызовет A деструктор - если он не был виртуальным, и вы можете получить утечку памяти, или другие неисправности.
  • Используя виртуальный деструктор - вы гарантируете, что деструктор B вызывается, поскольку объект B уничтожается .
2 голосов
/ 29 марта 2012

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

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 vtable , чтобы найти правильный деструктор.

Напротив, во время строительства вы всегда знаете, какой тип объекта вы создаете. (А если нет, то вы можете создать фабрику или « виртуальный конструктор », который знает.)

0 голосов
/ 29 апреля 2017
#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) вызовет деструктор базового класса но фактический девиз - удалить производный класс. поэтому нам нужно, чтобы деструктор был виртуальным по своей природе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...