Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 10, средняя оценка - 4.90
Antonioni
0 / 0 / 0
Регистрация: 17.07.2014
Сообщений: 12
#1

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

12.08.2014, 10:48. Просмотров 1377. Ответов 25
Метки нет (Все метки)

Недавно выполнял задание, и забыл в абстрактном классе(использовалось наследование) объявить виртуальный диструктор. С точки зрения профессионального программирования, является ли это серьёзной ошибкой?
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
12.08.2014, 10:48
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Обязательно ли объявление виртуального деструктора в абстрактном классе (C++):

Магия виртуального деструктора - C++
Если убрать определение virtual (стр. 18), то вызывается (47) только деструктор класса Person (деструктор Student не вызывается). Вопрос:...

Объяснить использование виртуального деструктора - C++
Ребят для чего здесь используется виртуальный деструктор? using namespace std; class Ostanovki { protected: char* name; ...

Написание функций, которые объявлены в абстрактном классе - C++
Добрый день. Подскажите, как написать тело функций, которые объявлены в абстрактном классе. Абстрактный класс: class OSM_EXPORT...

Возвращаемый тип конструктора копирования в абстрактном классе - C++
Здравствуйте! Есть абстрактный класс (с "чистыми" виртуальными функциями), и в нем необходимо явно определить конструктор копирования....

Создать массив в базовом абстрактном классе, и его передать функциям производных классов - C++
есть полностью абстрактный (виртуальный) класс. там все функции виртуальные и равны 0. Назовем его class A есть 3 производных ОТ НЕГО...

Двумерный динамический массив в классе. Зависание при вводе и вызове деструктора - C++
Объект класса содержит двумерный массив строк фиксированного размера(80) и длины n. При обращении к ф-ции ввода программа зависает и...

25
0x10
2482 / 1657 / 249
Регистрация: 24.11.2012
Сообщений: 4,125
12.08.2014, 11:05 #2
Цитата Сообщение от Antonioni Посмотреть сообщение
С точки зрения профессионального программирования, является ли это серьёзной ошибкой?
Да, поскольку потенциально ведет к утечкам памяти.

Special case с использованием сматрпоинтеров стандартной библиотеки не рассматриваем.
0
Kuzia domovenok
2030 / 1874 / 168
Регистрация: 25.03.2012
Сообщений: 6,452
Записей в блоге: 1
12.08.2014, 11:54 #3
0x10, почему именно к утечкам памяти? Разве деструкторы только памятью занимаются?
0
0x10
2482 / 1657 / 249
Регистрация: 24.11.2012
Сообщений: 4,125
12.08.2014, 12:06 #4
Kuzia domovenok, первое, что всегда вспоминается.

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

За полными, точными и понятными формулировками - прошу в стандарт/книги/etc.
1
Убежденный
Ушел с форума
Эксперт С++
15708 / 7218 / 1139
Регистрация: 02.05.2013
Сообщений: 11,637
Записей в блоге: 1
Завершенные тесты: 1
12.08.2014, 20:29 #5
Цитата Сообщение от Antonioni Посмотреть сообщение
С точки зрения профессионального программирования, является ли это серьёзной ошибкой?
Да. Абстрактные классы обычно создают, чтобы работать с ними
полиморфно, через наследников, маскирующихся за указателем на базу.

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

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

Не по теме:

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

0
Trwsdf
Заблокирован
12.08.2014, 21:02 #9
gromo, круто
0
Убежденный
Ушел с форума
Эксперт С++
15708 / 7218 / 1139
Регистрация: 02.05.2013
Сообщений: 11,637
Записей в блоге: 1
Завершенные тесты: 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 Посмотреть сообщение
В принципе, вещь доводящая до слез неграмотных программистов С++, вроде вас и "экспертов" сего форума
Поставил "-".
"За постоянные выпады в адрес форумчан".
1
Trwsdf
Заблокирован
12.08.2014, 22:05 #11
Цитата Сообщение от Убежденный Посмотреть сообщение
Trwsdf, вот вы и продемонстрировали свои "знания" языка,
который так не любите:
http://ideone.com/9d2Ti2 (режим C++11):
И? Не понял к чему это все. К тому, что я не люблю С++?, так и есть.
А наверно к тому, что некто тщательно штудирует интернет в поисках несоответствия моих слов с документацией, с маниакальным стремлением, доказать мне что я неправ.
И вот я сказал, что компилятор не выдаст ошибку, а он на самом деле выдает и некто со всеми порывами мчится доказать мне, что наконец то, подловил, ха ха, - что дескать я не прав, какой я дурень, сразу же отматывает мне цифры и т.д.

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

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

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

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

Добавлено через 5 минут
удачи уважаемые господа.
0
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 отсутствие виртуального диструктора за ошибку не считает, по этому нужно быть предельно внимательным!
0
Убежденный
Ушел с форума
Эксперт С++
15708 / 7218 / 1139
Регистрация: 02.05.2013
Сообщений: 11,637
Записей в блоге: 1
Завершенные тесты: 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 Посмотреть сообщение
удачи уважаемые господа.
Глубоко взаимно. Надеюсь, в таком ключе общаться больше не придется.
0
12.08.2014, 22:36
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
12.08.2014, 22:36
Привет! Вот еще темы с ответами:

Почему при переопределении виртуального метода в производном классе выводится метод базового? - C++
Всем добра! Помогите разобраться почему при переопределении виртуального метода в производном классе выводится метод базового ? По идеи...

Объявление переменных в классе - C++
#pragma once class streetdb { public: streetdb(void); ~streetdb(void); int admiral_1_137; private: };

Объявление операторов в классе - C++
Всем привет, объясните простым языком, когда используется ссылка(&amp;) и когда не используется. Вот например: Fraction&amp; operator += (const...

Объявление вектора в классе - C++
Здравствуйте! объявляю структуру в h файле: struct Admin { char login_admin; char pass_admin; }; class Nev_potok_blok { ...


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

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.