Форум программистов, компьютерный форум CyberForum.ru

Обязательно ли объявление виртуального деструктора в абстрактном классе - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 10, средняя оценка - 4.90
Antonioni
0 / 0 / 0
Регистрация: 17.07.2014
Сообщений: 12
12.08.2014, 10:48     Обязательно ли объявление виртуального деструктора в абстрактном классе #1
Недавно выполнял задание, и забыл в абстрактном классе(использовалось наследование) объявить виртуальный диструктор. С точки зрения профессионального программирования, является ли это серьёзной ошибкой?
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
12.08.2014, 10:48     Обязательно ли объявление виртуального деструктора в абстрактном классе
Посмотрите здесь:

Создать массив в базовом абстрактном классе, и его передать функциям производных классов C++
Объявление константы в классе C++
Объявление переменных в классе C++
Магия виртуального деструктора C++
Двумерный динамический массив в классе. Зависание при вводе и вызове деструктора C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
0x10
2425 / 1597 / 232
Регистрация: 24.11.2012
Сообщений: 3,919
12.08.2014, 11:05     Обязательно ли объявление виртуального деструктора в абстрактном классе #2
Цитата Сообщение от Antonioni Посмотреть сообщение
С точки зрения профессионального программирования, является ли это серьёзной ошибкой?
Да, поскольку потенциально ведет к утечкам памяти.

Special case с использованием сматрпоинтеров стандартной библиотеки не рассматриваем.
Kuzia domovenok
 Аватар для Kuzia domovenok
1883 / 1738 / 116
Регистрация: 25.03.2012
Сообщений: 5,907
Записей в блоге: 1
12.08.2014, 11:54     Обязательно ли объявление виртуального деструктора в абстрактном классе #3
0x10, почему именно к утечкам памяти? Разве деструкторы только памятью занимаются?
0x10
2425 / 1597 / 232
Регистрация: 24.11.2012
Сообщений: 3,919
12.08.2014, 12:06     Обязательно ли объявление виртуального деструктора в абстрактном классе #4
Kuzia domovenok, первое, что всегда вспоминается.

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

За полными, точными и понятными формулировками - прошу в стандарт/книги/etc.
Убежденный
Системный программист
 Аватар для Убежденный
14208 / 6223 / 987
Регистрация: 02.05.2013
Сообщений: 10,368
Завершенные тесты: 1
12.08.2014, 20:29     Обязательно ли объявление виртуального деструктора в абстрактном классе #5
Цитата Сообщение от Antonioni Посмотреть сообщение
С точки зрения профессионального программирования, является ли это серьёзной ошибкой?
Да. Абстрактные классы обычно создают, чтобы работать с ними
полиморфно, через наследников, маскирующихся за указателем на базу.

По стандарту языка C++, удаление объекта через указатель на базовый класс,
не имеющий виртуального деструктора - это неопределенное поведение (UB).
Легко сварганить пример, когда это приводит к аварийному завершению программы.
Antonioni
0 / 0 / 0
Регистрация: 17.07.2014
Сообщений: 12
12.08.2014, 20:54  [ТС]     Обязательно ли объявление виртуального деструктора в абстрактном классе #6
Спасибо большое за ответы!
Trwsdf
Заблокирован
12.08.2014, 20:56     Обязательно ли объявление виртуального деструктора в абстрактном классе #7
Цитата Сообщение от Antonioni Посмотреть сообщение
Недавно выполнял задание, и забыл в абстрактном классе(использовалось наследование) объявить виртуальный диструктор. С точки зрения профессионального программирования, является ли это серьёзной ошибкой?
нет, не страшно, если класс объявлен с ключевым словом final.
Если не используется полиморфизм - его не обязательно объявлять.

Если есть указатель, на базовый класс, и через него производится удаление, т.е. вызывается деструктор, то он просто вызовет деструктор базового класса, а не деструктор наследника, в итоге в памяти, удалится все, что относится к членам базового класса и останется все остальное.
В принципе, вещь доводящая до слез неграмотных программистов С++, вроде вас и "экспертов" сего форума- при проверке памяти, куда ж она все таки утекает.
gromo
12.08.2014, 20:59
  #8

Не по теме:

Цитата Сообщение от Trwsdf Посмотреть сообщение
нет, не страшно, если класс объявлен с ключевым словом final.
Если не используется полиморфизм - его не обязательно объявлять.
абстрактный final класс и НЕиспользование полиморфизма, имея базовый абстрактный класс

Trwsdf
Заблокирован
12.08.2014, 21:02     Обязательно ли объявление виртуального деструктора в абстрактном классе #9
gromo, круто
Убежденный
Системный программист
 Аватар для Убежденный
14208 / 6223 / 987
Регистрация: 02.05.2013
Сообщений: 10,368
Завершенные тесты: 1
12.08.2014, 21:08     Обязательно ли объявление виртуального деструктора в абстрактном классе #10
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Trwsdf, вот вы и продемонстрировали свои "знания" языка,
который так не любите:
http://ideone.com/9d2Ti2 (режим C++11):
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
struct mother
{
    virtual void func1() {}
};
     
struct father
{
    virtual void func2() {}
};
     
struct child : mother, father
{
};
     
int main()
{
    father * p = new child();
    delete p;
    return 0;
}
> Runtime error
Вот цитата из стандарта. Читайте, просвящайтесь:
C++03, Unary Expressions, Delete
In the first alternative (delete object), if the static type of the
operand is different from its dynamic type, the static type shall be a base
class of the operand’s dynamic type and the static type shall have a
virtual destructor or the behavior is undefined.
Цитата Сообщение от Trwsdf Посмотреть сообщение
В принципе, вещь доводящая до слез неграмотных программистов С++, вроде вас и "экспертов" сего форума
Поставил "-".
"За постоянные выпады в адрес форумчан".
Trwsdf
Заблокирован
12.08.2014, 22:05     Обязательно ли объявление виртуального деструктора в абстрактном классе #11
Цитата Сообщение от Убежденный Посмотреть сообщение
Trwsdf, вот вы и продемонстрировали свои "знания" языка,
который так не любите:
http://ideone.com/9d2Ti2 (режим C++11):
И? Не понял к чему это все. К тому, что я не люблю С++?, так и есть.
А наверно к тому, что некто тщательно штудирует интернет в поисках несоответствия моих слов с документацией, с маниакальным стремлением, доказать мне что я неправ.
И вот я сказал, что компилятор не выдаст ошибку, а он на самом деле выдает и некто со всеми порывами мчится доказать мне, что наконец то, подловил, ха ха, - что дескать я не прав, какой я дурень, сразу же отматывает мне цифры и т.д.

Стоит заметить однако, что так называемым самозванным "экспертам" с самонакрученными цифрами, сего форума не мешало бы открывать книги, например "Страуструп Б. Язык Программирования С++ - 2011" на странице 510. Страуструп не пишет не о каких ошибках компилятора, да и в других книгах тоже.

Ок, перефразирую так:
В принципе, вещь доводящая до слез неграмотных программистов С++, вроде вас и "экспертов" сего форума, при проверке , они снова и снова задаются вопросом, что ж ему не нравится, этому компилятору.
Суть та же, не правда ли? Но человек с энтузиазмом вырвав где то кусок чего то с документации, наконец увидтя какое то мелкое несоответствие кинулся отматывать мне цифры и доказывать, что я не прав.

Что я могу на это сказать, - вы не меня оскорбили и не мне напакостили , ибо вы для меня не авторитет - вы форуму напакостили , очередной раз не правда ли? чи впервой )). плюнули снова человеку в лицо, и снова потеряли людей. . Теперь в этой ветке только вы сами будете отвечать другим, да и темы создавать тоже.

Добавлено через 5 минут
Да, и еще хотел добивать, что теперь мне понятно окончательно и не удивительно, почему на этом форуме не осталось умных людей.
gromo
 Аватар для gromo
366 / 265 / 24
Регистрация: 04.09.2009
Сообщений: 1,214
12.08.2014, 22:05     Обязательно ли объявление виртуального деструктора в абстрактном классе #12
Цитата Сообщение от Trwsdf Посмотреть сообщение
наконец увидтя какое то мелкое несоответствие
ничего себе мелкое несоответствие В С++ это грубая ошибка - не до конца удалить объект
Trwsdf
Заблокирован
12.08.2014, 22:18     Обязательно ли объявление виртуального деструктора в абстрактном классе #13
Цитата Сообщение от gromo Посмотреть сообщение
ничего себе мелкое несоответствие В С++ это грубая ошибка - не до конца удалить объект
Еще бы, я сказал,что компилятор не выдаст ошибки и будет утечка памяти, а он на самом деле выдает ошибку.
Это не ошибка вообще.

Добавлено через 5 минут
удачи уважаемые господа.
Antonioni
0 / 0 / 0
Регистрация: 17.07.2014
Сообщений: 12
12.08.2014, 22:30  [ТС]     Обязательно ли объявление виртуального деструктора в абстрактном классе #14
В итоге пришлось мне самому написать прогу в 25 строчек
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
using namespace std;
 
class Base{
public:
    virtual void show() = 0;
    Base(){ cout << "Base()" << endl; }
    virtual ~Base(){ cout << "~Base()" << endl; }
};
 
class Child :public Base{
public:
    void show(){ cout << "Not virtual" << endl; }
    Child(){ cout << "Child()" << endl; }
    ~Child(){ cout << "~Child()" << endl; }
};
 
 
int main(){
    Base* obj1 = new Child();
    obj1->show();
    delete obj1;
 
    system("pause");
}
Действительно, только при виртульном диструкторе объект удаляется полностью.
В защиту Trwsdf скажу, что VS 2013 отсутствие виртуального диструктора за ошибку не считает, по этому нужно быть предельно внимательным!
Убежденный
Системный программист
 Аватар для Убежденный
14208 / 6223 / 987
Регистрация: 02.05.2013
Сообщений: 10,368
Завершенные тесты: 1
12.08.2014, 22:36     Обязательно ли объявление виртуального деструктора в абстрактном классе #15
Цитата Сообщение от Trwsdf Посмотреть сообщение
А наверно к тому, что некто тщательно штудирует интернет в поисках несоответствия моих слов с документацией, с маниакальным стремлением, доказать мне что я неправ.
И вот я сказал, что компилятор не выдаст ошибку, а он на самом деле выдает и некто со всеми порывами мчится доказать мне, что наконец то, подловил, ха ха, - что дескать я не прав, какой я дурень, сразу же отматывает мне цифры и т.д.
Trwsdf, ты сам спровоцировал такую форму ответа. И не только в этой теме.
Достаточно бегло посмотреть историю твоих сообщений, и все сразу станет ясно.
Так что уж не обижайся.

Цитата Сообщение от Trwsdf Посмотреть сообщение
Стоит заметить однако, что так называемым самозванным "экспертам" с самонакрученными цифрами, сего форума не мешало бы открывать книги, например "Страуструп Б. Язык Программирования С++ - 2011" на странице 510. Страуструп не пишет не о каких ошибках компилятора,
Но он пишет дословно следующее:
Присутствие в классе [Employee] виртуального деструктора гарантирует,
что каждый производный класс будет обладать деструктором (обеспечивающим
информацию о правильном размере объекта)
Цитата Сообщение от Trwsdf Посмотреть сообщение
да и в других книгах тоже.
Бью навскидку (первая попавшаяся книга Бьерна):

"Программирование. Практика и принципы использования C++", стр. 615
Если бы деструктор [Shape::~Shape] не был виртуальным, то деструктор
[Text::~Text] не был бы вызван и член класса Text, имеющий тип string,
не был бы правильно уничтожен.

...

Запомните правило: если класс содержит виртуальную функцию, в нем
должен быть виртуальный деструктор.
Цитата Сообщение от Trwsdf Посмотреть сообщение
Что я могу на это сказать, - вы не меня оскорбили и не мне напакостили , ибо вы для меня не авторитет - вы форуму напакостили , очередной раз не правда ли? чи впервой )). плюнули снова человеку в лицо, и снова потеряли людей.
Trwsdf, отвечай за слова, или балабол:

1) Где я пакостил форуму ?
2) В каком месте плюнул в лицо перед тем, как наступило "снова" ?

Цитата Сообщение от Trwsdf
Теперь в этой ветке только вы сами будете отвечать другим, да и темы создавать тоже.
А раньше это за меня что, роботы делали ?

Цитата Сообщение от Trwsdf Посмотреть сообщение
Да, и еще хотел добивать, что теперь мне понятно окончательно и не удивительно, почему на этом форуме не осталось умных людей.
Раз форум такой плохой, почему ты до сих пор здесь ?

Добавлено через 2 минуты
Цитата Сообщение от Trwsdf Посмотреть сообщение
удачи уважаемые господа.
Глубоко взаимно. Надеюсь, в таком ключе общаться больше не придется.
Trwsdf
Заблокирован
12.08.2014, 23:17     Обязательно ли объявление виртуального деструктора в абстрактном классе #16
Омг... я должен на все это отвечать ?
Цитата Сообщение от Antonioni Посмотреть сообщение
Действительно, только при виртульном диструкторе объект удаляется полностью.
В защиту Trwsdf скажу, что VS 2013 отсутствие виртуального диструктора за ошибку не считает, по этому нужно быть предельно внимательным!
Был бы смысл доказывать, если бы оппонент был и правда компетентным человеком.

Добавлено через 18 минут
еще раз прочитал тему, и понял несостоятельность критики в мой адрес.
А именно - да, в документации написано, что результат не определен.
Стало быть, реализация GNU (например) выдаст ошибку, а реализация от Microsoft просто сделает утечку памяти ( о чем я и писал в первом ответе ).
Ведь результат не определен, - каждая реализация вправе его выдавать по своему.
ValeryS
Модератор
6377 / 4843 / 442
Регистрация: 14.02.2011
Сообщений: 16,051
12.08.2014, 23:37     Обязательно ли объявление виртуального деструктора в абстрактном классе #17
Цитата Сообщение от Antonioni Посмотреть сообщение
В защиту Trwsdf скажу, что VS 2013 отсутствие виртуального диструктора за ошибку не считает, по этому нужно быть предельно внимательным!
есть много что не считается за ошибку
например
C++
1
if(a=b)
и отсутствие виртуального деструкторатоже не всегда ошибка
например
у наследников переопределены только методы, новых членов, а тем паче указателей нет
и тогда главный деструктор вполне справится
так что это ошибка не синтаксинечкая, кои компилятор должен отлавливать, а лгоритмическая, проектирования
за этим человек должен следить
Trwsdf
Заблокирован
13.08.2014, 01:01     Обязательно ли объявление виртуального деструктора в абстрактном классе #18
Цитата Сообщение от ValeryS Посмотреть сообщение
есть много что не считается за ошибку
например
Код C++
1
if(a=b)
и отсутствие виртуального деструкторатоже не всегда ошибка
например
у наследников переопределены только методы, новых членов, а тем паче указателей нет
и тогда главный деструктор вполне справится
так что это ошибка не синтаксинечкая, кои компилятор должен отлавливать, а лгоритмическая, проектирования
за этим человек должен следить
Вы не правы в обоих случаях.
при a=b нет никакой ошибки оттого, что он присваивает a число b, после чего значение a неявно приводит к bool.

Насчет деструктора (поздравляю, вы все же осилили этот материал), всегда надо страховаться и писать его, ибо потом кто то сломает голову пытаясь найти ошибку, при поддержке кода, исключение составляют классы объявленные с ключевым словом final. Ито в том случае, если компилятор не выдает ошибки. В этой ситуации, каждый компилятор ведет себя по своему.
Хотел также заметить, что очень долго вы разбирались, видимо дается с трудом.
ValeryS
Модератор
6377 / 4843 / 442
Регистрация: 14.02.2011
Сообщений: 16,051
13.08.2014, 01:33     Обязательно ли объявление виртуального деструктора в абстрактном классе #19
Цитата Сообщение от Trwsdf Посмотреть сообщение
при a=b нет никакой ошибки оттого, что он присваивает a число b, после чего значение a неявно приводит к bool.
спасибо что просвятил
Цитата Сообщение от Trwsdf Посмотреть сообщение
Насчет деструктора (поздравляю, вы все же осилили этот материал), всегда надо страховаться и писать его,
мы этот материал осилили лет так двадцать назад, причем на живых примерах а не зачитываясь талмудами и не ссылались на них ка на истину в последней инстанции
За сим разрешите откланяться, превращать нормальную тему в пипискометр нет никакого желания
Мои знания достаточно объективно оценивают работодатели
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
13.08.2014, 01:52     Обязательно ли объявление виртуального деструктора в абстрактном классе
Еще ссылки по теме:

C++ Возвращаемый тип конструктора копирования в абстрактном классе
Почему при переопределении виртуального метода в производном классе выводится метод базового? C++
Объяснить использование виртуального деструктора C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
ct0r
C++/Haskell
 Аватар для ct0r
1549 / 568 / 39
Регистрация: 19.08.2012
Сообщений: 1,174
Завершенные тесты: 1
13.08.2014, 01:52     Обязательно ли объявление виртуального деструктора в абстрактном классе #20
Цитата Сообщение от Trwsdf Посмотреть сообщение
Еще бы, я сказал,что компилятор не выдаст ошибки и будет утечка памяти, а он на самом деле выдает ошибку.
Компилятор и не выдает никакой ошибки. Это же runtime-ошибка, а не compile-time.
Цитата Сообщение от Trwsdf Посмотреть сообщение
еще раз прочитал тему, и понял несостоятельность критики в мой адрес.
А именно - да, в документации написано, что результат не определен.
Стало быть, реализация GNU (например) выдаст ошибку, а реализация от Microsoft просто сделает утечку памяти ( о чем я и писал в первом ответе ).
Ведь результат не определен, - каждая реализация вправе его выдавать по своему.
Ты неправильно понимаешь термин undefined behavior. Там поведение зависит не только от особенностей реализации компилятора и его опций, но и от состояния памяти в данный момент времени. То есть можно легко получать разные ошибки на разных системах, несмотря на то, что программа собиралась каким-то конкретным компилятором и она одна. Ты же говоришь не про undefined behavior, а про implementation-defined или unspecified behavior. Но в данном случае имеет место именно undefined behavior, а его допущение - грубая ошибка разработчика.
Yandex
Объявления
13.08.2014, 01:52     Обязательно ли объявление виртуального деструктора в абстрактном классе
Ответ Создать тему
Опции темы

Текущее время: 02:14. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru