C++ деструкторы наследование

Виртуальный деструктор в C++

В языке программирования C++ деструктор полиморфного базового класса должен объявляться виртуальным. Только так обеспечивается корректное разрушение объекта производного класса через указатель на соответствующий базовый класс.

Рассмотрим следующий пример.

В функции main указателю на базовый класс присваивается адрес динамически создаваемого объекта производного класса Derived. Затем через этот указатель объект разрушается. При этом наличие виртуального деструктора базового класса обеспечивает вызовы деструкторов всех классов в ожидаемом порядке, а именно, в порядке, обратном вызовам конструкторов соответствующих классов.

Вывод программы с использованием виртуального деструктора в базовом классе будет следующим:

Уничтожение объекта производного класса через указатель на базовый класс с невиртуальным деструктором дает неопределенный результат. На практике это выражается в том, что будет разрушена только часть объекта, соответствующая базовому классу. Если в коде выше убрать ключевое слово virtual перед деструктором базового класса, то вывод программы будет уже иным. Обратите внимание, что член данных obj класса Derived также не разрушается.

Когда же следует объявлять деструктор виртуальным? Cуществует правило — если базовый класс предназначен для полиморфного использования, то его деструктор должен объявляться виртуальным. Для реализации механизма виртуальных функций каждый объект класса хранит указатель на таблицу виртуальных функций vptr, что увеличивает его общий размер. Обычно, при объявлении виртуального деструктора такой класс уже имеет виртуальные функции, и увеличения размера соответствующего объекта не происходит.

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

Наследование конструктора и деструктора

Я считаю, что Constructors и Destructors в base class не могут быть унаследованы derived classes базового класса. Правильно ли я понимаю.

Ваше понимание верное. Например, если у вас есть

Это не будет компилироваться, потому что базовый конструктор не наследуется. Обратите внимание, что конструктор по умолчанию и копии создаются компилятором, если это возможно, и вызывают соответствующий конструктор базовых классов, поэтому для этих конструкторов он выглядит так, как если бы они были наследованы.

Я думаю, что это то, что вы ищете? Вы можете вызвать конструктор суперкласса, добавив следующее к вашему конструктору класса

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

Напротив, каждый конструктор производного класса вызывает конструктор базового класса [super-]. Каждый деструктор производного класса вызывается непосредственно перед деструктором базового класса [super-].

Наследование относится к классам, а не к функциям или конструкторам.

Нет, они наследуются. Деструкторы, для одного, всегда унаследованы и вызваны в порядке, обратном созданию. Например, если у нас есть классы foo , bar и xyzzy :

Смотрите так же:  Заявление силуанова о повышении пенсионного возраста

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

Конструкторы также всегда унаследованы, но они не могут быть вызваны напрямую. Вы должны использовать их в списке инициализации конструктора или вызывать конструктор по умолчанию (конструктор по умолчанию — тот, который не принимает никаких аргументов). Например, скажем, что у нас есть следующие классы:

В этом случае при создании объекта класса bar вызывается конструктор для foo , но это конструктор по умолчанию ( foo() ). Конструктор, который принимает аргумент foo (int _value) , никогда не вызывается. Но если мы изменили определение конструктора bar (int _value) на это:

Затем вместо конструктора по умолчанию будет вызываться foo (int _value) .

Деструкторы и наследование в С++?

Я использую Borland С++ Builder.

И у меня была проблема

И для этого нового деструктора, который наследует

Это можно решить на уровне TObject . Его деструктор должен быть виртуальным:

Таким образом вы можете:

Оба деструктора будут вызваны (

TMyObject() сначала, а затем

TObject() ), и у вас не будет утечки.

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

Не наследует конструктор.
Он называется список инициаторов Member, и он инициализирует объект класса Base определенным значением.

При создании объекта.

Конструкторы будут вызываться по порядку:

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

Компилятор сделает это за вас, не нужно явно вызывать его.

Что вызывает у вас путаница, так это то, что вы можете конкретно указать «какой» конструктор базового класса, который вы хотите использовать, как в следующем примере. Но вы не можете/не должны указывать деструктор.

Вы можете использовать другой конструктор, например TObject (int i) , написав

Объект может быть уничтожен только одним способом, но он может быть сконструирован несколькими способами (с помощью разных конструкторов).

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

Если вы уничтожили TMyObject с помощью ссылки типа TMyObject , вам не нужно ничего делать. Если у вас есть указатель/ссылка типа TObject на TMyObject , все будет не так. Будет вызываться только деструктор TObject , а не TMyObject один:

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

Смотрите так же:  На постоянной основе договор

Конструкторы и деструкторы производных классов

При использовании производных классов важно представлять себе, каким образом и когда ис­полняются конструкторы и деструкторы базового и производного классов. Начнем рассмотрение с конструкторов.

Как базовый класс, так и производный класс могут иметь конструкторы. (В многоуровневой иерархии классов каждый из классов может иметь конструкторы, но мы начинаем с наиболее простого случая.) Когда базовый класс имеет конструктор, этот конструктор исполняется перед конструктором производного класса. Например, рассмотрим следующую короткую программу:

#include
class Base <
public:
Base () class Base <
public:
Base() class Base <
public:
Base()

Деструкторы при наследовании от абстрактного класса

DoubleObject()<> и нужно ли создавать виртуальный деструктор класса IObject

Конструкторы и деструкторы при наследовании. Пара вопросов
1. Можно ли создавать виртуальный конструктор/деструктор и переопределять его без создания нового.

Ошибка при наследовании класса
Всем доброго времени суток, пытаюсь отнаследовать класс, вот такой код я смастерил: #ifndef.

Ошибки при наследовании класса
Доброго времени суток!Возникли ошибки при компиляции кода Задание было такое:Создать абстрактный.

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

Segmentation fault при наследовании класса
Доброго времени суток! Имею класс Initialise и класс Environment. В первом создаются экземпляры.

Наследование — это механизм создания нового класса на основе уже существующего. При этом к существующему классу могут быть добавлены новые элементы (данные и функции), либо существующие функции могут быть изменены. Основное назначение механизма наследования — повторное использование кодов, так как большинство используемых типов данных являются вариантами друг друга, и писать для каждого свой класс нецелесообразно.
Объекты разных классов и сами классы могут находиться в отношении наследования, при котором формируется иерархия объектов, соответствующая заранее предусмотренной иерархии классов.

Иерархия классов позволяет определять новые классы на основе уже имеющихся. Имеющиеся классы обычно называют базовыми (иногда порождающими), а новые классы, формируемые на основе базовых, – производными (порожденными, классами-потомками или наследниками).

Производные классы «получают наследство» – данные и методы своих базовых классов, и могут пополняться собственными компонентами (данными и собственными методами). Наследуемые компоненты не перемещаются в производный класс, а остаются в базовых классах. Сообщение, обработку которого не могут выполнить методы производного класса, автоматически передается в базовый класс. Если для обработки сообщения нужны данные, отсутствующие в производном классе, то их пытаются отыскать автоматически в базовом классе.

При наследовании некоторые имена методов (функций-членов) и полей (данных-членов) базового класса могут быть по-новому определены в производном классе. В этом случае соответствующие компоненты базового класса становятся недоступными из производного класса. Для доступа из производного класса к компонентам базового класса, имена которых повторно определены в производном, используется операция разрешения контекста ::

Смотрите так же:  Седьмой арбитражный суд официальный сайт

Для порождения нового класса на основе существующего используется следующая общая форма

При объявлении порождаемого класса МодификаторДоступа может принимать значения public , private , protected либо отсутствовать, по умолчанию используется значение private . В любом случае порожденный класс наследует все члены базового класса, но доступ имеет не ко всем. Ему доступны общие ( public ) члены базового класса и недоступны частные ( private ).

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

Члены класса с доступом protected видимы в пределах класса и в любом классе, порожденном из этого класса.

Общее наследование

При общем наследовании порожденный класс имеет доступ к наследуемым членам базового класса с видимостью public и protected . Члены базового класса с видимостью private – недоступны.

Другие публикации:

  • Windows 7 professional 32 bit лицензия Windows 7 оригинальные образы Windows 7 оригинальный образ торрент будет еще популярным много лет, и после десятки и даже если выйдут другие версии операционных систем от компании microsoft. Связано это с тем, что люди привыкают к хорошему. винда семёрка […]
  • Шаламов и завещание ленина Шаламов и завещание ленина Если РІС‹ видите эту страницу, значит СЃ вашего IP-адреса поступило необычно РјРЅРѕРіРѕ запросов. Система защиты РѕС‚ роботов решила, что […]
  • До скольки лет нужна доверенность на ребенка по россии Выезд ребенка за границу с одним родителем: нужно ли разрешение Очень часто, когда один из родителей собирается с ребенком поехать за границу отдохнуть или на лечение, встает вопрос: нужно ли разрешение второго родителя и в случае необходимости как его […]
  • Заявление по форме банка в росгосстрах Как оформить кредит наличными в Росгосстрах Банке? Если вам срочно понадобились деньги на покупку того или иного товара, но вы не располагаете нужной суммой, вы всегда можете обратиться в проверенную банковскую организацию. Дорогие читатели! Статья […]
  • Услуги адвоката в нижнем новгороде цены Услуги адвоката в нижнем новгороде цены 2 Гражданские дела 2.1 Составление искового заявления, ходатайства - 3000 руб. 2.2 Полное участие адвоката во всех судебных заседаниях суда первой инстанции - от 10000 руб. 2.3 Составление кассационной жалобы - 3000 […]
  • Форма заявления на предоставление льготы Как написать заявление о предоставлении льготы на транспортный налог? В соответствии с налоговым законодательством, все владельцы транспортных средств обязаны регулярно делать взносы. Но некоторые люди имеют определенные причины, в связи с ними сумма налога […]

Вам также может понравиться