![]() |
|
Модераторы: bsa |
![]()
|
|
| Riddik |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 598 Регистрация: 2.12.2006 Репутация: нет Всего: нет |
Вопрос, скорее всего, дурацкий, но мне для успокоения
Есть два классы, пусть Monstr и Male, в их конструкторе выделяется память, в деструкторе - освобождается. Эти классы помещаются в контейнер типа вектор, содержащий указатель на базовый класс, из которого выведены Monstr и Male:
Затем, когда возникает необходимость, контейнер очищается :
Вопрос: когда очищается контейнер таким способом, вызывается ли деструктор класса Monstr и деструктор класса Male? Другими словами, та память, что выделяется их конструкторами, освобождается? Или для успокоения написать отдельную функцию, которая будет это делать и вызывать её вместе с очисткой контейнера? Это сообщение отредактировал(а) Riddik - 6.5.2009, 00:32 |
||||
|
|||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
Вызов деструктора наследника, будет произведен, только если он помечен виртуальным в базовом.
Вектор указателей, при очищении не удаляет объекты. Это Вы должны сделать самостоятельно. исправлено Это сообщение отредактировал(а) mes - 6.5.2009, 02:23 |
|||
|
||||
| Riddik |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 598 Регистрация: 2.12.2006 Репутация: нет Всего: нет |
mes, не понял, простите. Если сделать виртуальный деструктор в базовом?
|
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
да. (в наследниках он автоматическки получится тоже виртуальный.) |
|||
|
||||
| Riddik |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 598 Регистрация: 2.12.2006 Репутация: нет Всего: нет |
Как же его объявить, возникают ошибки, не хочет компилироваться:
или
? Это сообщение отредактировал(а) Riddik - 6.5.2009, 00:42 |
||||
|
|||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
Вы ошибки то читаете ? там же ясным языком написано, что нет определения у функции. Или Вы на ощупь программируете ?
|
|||
|
||||
| Riddik |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 598 Регистрация: 2.12.2006 Репутация: нет Всего: нет |
И ещё такой момент, есть просто указать на базовый класс, которому выделяется память на производный из него:
Затем память удаляется: delete p; Естественно, деструктор класса Monstr вызван не будет? То же самое, что с pbase.clear() ? Добавлено через 2 минуты и 56 секунд mes, на ощупь, конечно. Я, если честно, про такие инструкции virtual ~base() {} ничего не знаю ещё. Спасибо Добавлено через 4 минуты и 13 секунд Это так же вызовет деструктор classA и при p=new classA; delete p; ? |
|||
|
||||
| mes |
|
||||||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
а также то что у вызываемой функции должно быть тело. А самое главное, что, к сожалению, даже не попытались обдумать сообщение компилятора. ибо сегодня в соседней теме Вам уже сообщали о решении подобной проблемы.
Нет. Есть указатель, котоорый инизиализируется адресом новосозданного объекта.
при delete автоматически вызывается деструктор. Если он был объявлен как виртуальный, то вызовется и для наследникa (Monstr) нет, не то же самое. В delete "скрыт" вызов деструктора, а clear () - обычная функция. Это сообщение отредактировал(а) mes - 6.5.2009, 00:56 |
||||||
|
|||||||
| Riddik |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 598 Регистрация: 2.12.2006 Репутация: нет Всего: нет |
У функции должно быть тело, а как же чисто виртуальные ф-ии
virtual void func()=0; почему не virtual void func() {} Добавлено @ 01:10 поискал в соседней теме - не нашёл, где мне сообщили о решении подобной проблеме, речь шла об абстрактном классе, а проблема была в том, что его наследники получились тоже абстрактными. Про деструкторы и {} там мне ничего не говорили. Это сообщение отредактировал(а) Riddik - 6.5.2009, 01:10 |
|||
|
||||
| J0ker |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 986 Регистрация: 17.9.2008 Репутация: 9 Всего: 14 |
Riddik, у вас в голове каша
учите матчасть |
|||
|
||||
| Riddik |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 598 Регистрация: 2.12.2006 Репутация: нет Всего: нет |
J0ker, Да учу я, но и бегу вперёд поезда
Добавлено через 1 минуту и 46 секунд :( |
|||
|
||||
| J0ker |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 986 Регистрация: 17.9.2008 Репутация: 9 Всего: 14 |
уясните для начала разницу между pure virtual, virtual и abstract
|
|||
|
||||
| Riddik |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 598 Регистрация: 2.12.2006 Репутация: нет Всего: нет |
pure virtual, virtual и abstract
вы будете смеятся, но в тех книжках, которые я уже прочёл, об этом ни слова Добавлено через 21 секунду вернее только про virtual |
|||
|
||||
| J0ker |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 986 Регистрация: 17.9.2008 Репутация: 9 Всего: 14 |
значит вы читали что-то не по С++
|
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
я специально сделал акцент на слово вызываемая. У виртуальных функций, тело связывается с вызовом в рантайме (в отличие от обычных - на этапе линковки). И чтоб не было возможности вызвать функцию, у которой нет связи с телом, нельзя создавать объекты абстрактных классов. Да фраза не совсем корректная, но она намекала на возможный ход мыслей, когда бы Вы прочитали ошибку компилятора. Там написано : не хватает тела функции. Следовательно Вы должны были подумать как объяснить компилятору, где искать. или написать тело или пометить чисто-виртуальной (ну или и то другое, но Вам это рано) P.S У деструктора, тело должно быть всегда, даже когда он помечен, как чистая виртуальная функция. У виртуальных функций, тело может быть не определено, но должнa быть метка "чистоты" . Если у класса есть хоть одна функция, помеченная как "чистая", то объект такого класса нельзя создать. |
|||
|
||||
| Riddik |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 598 Регистрация: 2.12.2006 Репутация: нет Всего: нет |
Купник. Изучаем С++
Франка. Самоучитель С++ Шилдт. Базовый курс С++ Добавлено через 1 минуту и 41 секунду mes, спасибо большое |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
так тоже можно, чистые функции объявляются для того, если хотите использовать указатель на базовый класс как интерфейс, и объект подобного типа Вам не нужен. Это сообщение отредактировал(а) mes - 6.5.2009, 01:29 |
|||
|
||||
| Riddik |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 598 Регистрация: 2.12.2006 Репутация: нет Всего: нет |
mes, ещё раз спасибо за объяснения!
Значит в любом случае у деструктора должно быть тело ф-ии, даже если это чисто-виртуальный деструктор в абстрактном классе. P.S. Понимаю, что опытных программистов должно бы быть раздражает, когда говорят такие вещи, как я говорил здесь про память и указатели на неё, вроде "укзатель на базовый класс, ему выделяется память" - на самом деле уж это я понимаю, что выделяется память и адрес этой памяти присваивается указателю, а сказал небрежно, каюсь |
|||
|
||||
| mes |
|
||||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
Да.
Создается объект. А выделение памяти это всего лишь один из этапов создания объекта. |
||||
|
|||||
| Riddik |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 598 Регистрация: 2.12.2006 Репутация: нет Всего: нет |
Не буду умничать
|
|||
|
||||
| Riddik |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 598 Регистрация: 2.12.2006 Репутация: нет Всего: нет |
с delete всё нормально - вызывается деструктор, в если очищать вектор - не вызывается
Результат: выводит по пять строк "This is constructor А" и "This is constructor B", деструктор молчит. А если base *p=new A; затем delete p, то всё нормально, деструктор A вызывается Это сообщение отредактировал(а) Riddik - 6.5.2009, 02:08 |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
естественно, В векторе Вы храните указатели, а не объекты. За удаление "реальных" объектов он не отвечает. Это сообщение отредактировал(а) mes - 6.5.2009, 02:17 |
|||
|
||||
| Riddik |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 598 Регистрация: 2.12.2006 Репутация: нет Всего: нет |
Не понял, во втором сообщении Вы же ответили "только если он виртуальный в базовом" на вопрос "когда очищается контейнер таким способом, вызывается ли деструктор класса Monstr"
Сорри, уже поздно, наверное я плохо понимаю |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
сорри за невнимательность и за то что ввел в заблуждение, я там ответил только на половину вопроса - исправил. Ага, и на меня тоже сказывается Это сообщение отредактировал(а) mes - 6.5.2009, 02:26 |
|||
|
||||
| Riddik |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 598 Регистрация: 2.12.2006 Репутация: нет Всего: нет |
Ясно
Вот так нормально самому память освобождать:
Это сообщение отредактировал(а) Riddik - 6.5.2009, 02:33 |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
да
|
|||
|
||||
| Riddik |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 598 Регистрация: 2.12.2006 Репутация: нет Всего: нет |
Тогда вопрос решён - спасибо за всё
|
|||
|
||||
| azesmcar |
|
||||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 52 Всего: 211 |
вот так будет универсальнее, напишите функтор
вызов
будет работать для любого (STL совместимого) контейнера Это сообщение отредактировал(а) azesmcar - 6.5.2009, 09:17 |
||||
|
|||||
| Riddik |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 598 Регистрация: 2.12.2006 Репутация: нет Всего: нет |
azesmcar, благодарю.
|
|||
|
||||
![]()
|
| Правила форума "C/C++: Для новичков" | |
|
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Для новичков | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |