Понимание поведения деструктора C ++ в производном классе - PullRequest
2 голосов
/ 10 июля 2019

Я читаю фрагмент кода из книги программирования Страуструпа на C ++.

class Vector_container : public Container {
    Vector v;
public:    
    // Vector_container implements Container
    Vector_container(int s) : v(s) { } // Vector of s elements
    ~Vector_container() {}

    double& operator[](int i) { return v[i]; }
    int size() const { return v.size(); }    
};

Затем автор говорит:

  1. Деструктор (~Vector_container()) заменяет деструктор базового класса (~Container()).
  2. Обратите внимание, что деструктор члена (~Vector()) неявно вызывается деструктором его класса (~Vector_container()).

Относительно # 1, почему происходит переопределениев функциях разных имен?

Что касается # 2, является ли особенностью C ++ то, что деструкторы-члены систематически вызываются деструктором класса?

Ответы [ 4 ]

3 голосов
/ 10 июля 2019

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

И да, члены и базовые классы уничтожаются после вызова деструктора класса. От cppreference.com :

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

2 голосов
/ 10 июля 2019

Что касается # 1, почему переопределение происходит в функциях с разными именами?

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

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

Относительно # 2, это особенность C ++, что деструкторы-члены систематическивызывается деструктором класса?

Да, деструктор вызывает деструкторы из всех членов.

Подсказка: если элемент является необработанным указателем, деструктор только «уничтожает»указатель, а не элемент, на который он указывает.Поэтому вы должны либо использовать умные указатели, либо позаботиться о том, чтобы удалить все свои собственные объекты в деструкторе, предоставленном пользователем, который вы создали в другом месте.

2 голосов
/ 10 июля 2019

1: Деструктор - это специальная функция, имя здесь не имеет значения.

2: Да, это функция C++.Поскольку элемент v объявлен как Vector v, деструктор контейнера будет вызывать деструктор своего члена Vector::~Vector автоматически

1 голос
/ 10 июля 2019

почему переопределение происходит в функциях с разными именами?

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

Синтаксис для определения конструкторов и деструкторов немного сбивает с толку, потому что технически эти вещи не имеют имен ( ref ; нет конкретной формулировки для dtor, но то же самое применимо к дедуктивным рассуждениям) .Вы можете ссылаться на деструктор класса с синтаксисом ~<class name> ( ref ) , но это не само по себе имя функции.Это может звучать как чисто академическое различие, и, ну, это… но это может помочь сделать «переопределение другого имени» менее удивительным.

Я бы также не назвал это «переопределением», обычно это терминиспользуется для описания работы виртуальных функций.Бьярне использует его свободно.

Является ли это особенностью C ++, что деструкторы-члены систематически вызываются деструктором класса?

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

...