Как вы гарантируете, что деструктор Derived2 называется?

0
#include <iostream>

using namespace std;

class Base
{
    public:
        Base ( )
        {
            cout << "Inside Base constructor" << endl;
        }

        ~Base ( )
        {
            cout << "Inside Base destructor" << endl;
        }

};

class Derived : public Base
{
    public:    
        Derived  ( )
        {
        cout << "Inside Derived constructor" << endl;
        }

        ~Derived ( )
        {
            cout << "Inside Derived destructor" << endl;
        }
};

class Derived2 : public Base
{
    public:
        static void bogus(Derived2* d)
        {
            cout << "bogus" << endl;
        }

        Derived2  ( )
        {
            cout << "Inside Derived2 constructor" << endl;
        }

        ~Derived2 ( )
        {
            cout << "Inside Derived2 destructor" << endl;
        }
};

int main( )
{
    Derived y;
    Derived2::bogus( new Derived2 ());

    return 0;
}

-

>Inside Base constructor
>Inside Derived constructor
>Inside Base constructor
>Inside Derived2 constructor
>bogus
>Inside Derived destructor
>Inside Base destructor
>Press <RETURN> to close this window...

Я тестировал некоторые вещи и нашел это странное поведение. Почему деструктор не вызывается, когда мы создаем объект внутри поля параметров? Есть ли какое-нибудь решение, даже если это необходимо, есть ли утечка памяти?

  • 0
    Что ж, программа будет удерживать объект до тех пор, пока он не выйдет из области видимости, и даже тогда сборщик мусора, кажется, проходит в случайные моменты времени. Деструктор обязательно должен быть вызван, вопрос в том, когда. Кроме того, вы Derived2 статичны, это будет поддерживать его в течение всей жизни программы, в которую я верю.
  • 0
    почему это статично?
Теги:
destructor

3 ответа

4
Лучший ответ

Прежде всего - когда вы делаете классы друг от друга, вы должны убедиться, что деструкторы являются virtual. Если вы этого не сделаете, у вас могут быть утечки памяти, если классы-получатели имеют дополнительные члены:

virtual ~Base ( )
{
  cout << "Inside Base destructor" << endl;
}

Во-вторых - когда вы выделяете память с помощью new, деструктор не будет вызываться на созданном объекте, пока вы не удалите его вручную с помощью delete:

int main( )
{
  Derived y;
  Derived2 *ptr = new Derived2();
  Derived2::bogus(ptr);
  delete ptr;
  return 0;
}

Если вы не знаете, когда удалять объект, используйте std::shared_ptr или удалите его внутри деструктора класса, беря его в качестве параметра. Обратите внимание, что shared_ptr доступен только для С++ 11, если вы используете более старую версию (например, все еще много людей), попробуйте использовать библиотеку boost.

  • 0
    «когда вы делаете классы производными друг от друга, вы должны убедиться, что деструкторы являются виртуальными» - нет, вы этого не делаете. Также не стоит делать это во всех классах, из которых вы производите.
  • 0
    @ лучше? :)
Показать ещё 8 комментариев
1

Независимо от того, что создано new нужно delete. Здесь вы создаете объект temp. Попробуйте создать перед тем, как перейти к функции. Также сделайте base destructor virtual.

int main( )
{

  Derived y;
  Derived2 *d2 = new Derived2();
  Derived2::bogus( d2);

  delete d2;

  return 0;
}
1

Вы не создаете объект внутри поля параметров. Вы создаете объект в свободном хранилище (aka heap). Вы должны вызвать delete, чтобы уничтожить его. Для everey new должно быть удаление. Есть утечка памяти!

  • 0
    почему вызывается деструктор, хотя я явно не использовал delete?
  • 0
    Вы опубликовали вывод вызова деструктора для Derived, который выделен в стеке. Нет выходных данных из Derived2.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню