Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.73/11: Рейтинг темы: голосов - 11, средняя оценка - 4.73
1 / 1 / 0
Регистрация: 18.03.2011
Сообщений: 56

Действительно ли так необходим виртуальный деструктор?

11.02.2022, 23:24. Показов 2539. Ответов 27

Студворк — интернет-сервис помощи студентам
Подскажите пожалуйста по сабжу. Вычитал, что если использовать наследование и применять ссылки на родительский класс, указывающие на предков, вот это вот все, то необходимо использовать виртуальный деструктор и переопределять его в наследниках, т.к. при удалении наследника через ссылку родителя, то уничтожится ТОЛЬКО часть родителя, а часть наследника будет висеть и утечка памяти.
Сделал проверку следующим кодом

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
 
class Parent {
public:
    int x = 3;
    virtual int get() { return x; }
    virtual const char* print() const { return "it's Parent"; }
};
 
class Child : public Parent {
public:
    int y = 777;
    double ara[100000]{ 0 };
    virtual int get()override { return y; }
    virtual const char* print() const override { return "it's Child"; }
};
 
int main() {
    Parent* a = new Child;
    delete a;
 
    return 0;
}
размер кучи:
до удаления поинтера 833КB
после удаления поинтера 52КВ

Изменил код, что бы в конструкторе потомка было динамическое выделение памяти
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
26
#include <iostream>
 
class Parent {
public:
    int x = 3;
    virtual int get() { return x; }
    virtual const char* print() const { return "it's Parent"; }
};
 
class Child : public Parent {
public:
    Child() {
        new double[100000];
    }
    int y = 777;
    double ara[100000]{ 0 };
    virtual int get()override { return y; }
    virtual const char* print() const override { return "it's Child"; }
};
 
int main() {
    Parent* a = new Child;
    delete a;
 
    return 0;
}
размер кучи:
до удаления поинтера 1614КB
после удаления поинтера 833КВ

И вроде как получается, что если динамического выделения нет, то можно и не делать деструктор. Или я что-то упускаю?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
11.02.2022, 23:24
Ответы с готовыми решениями:

Почему создается виртуальный деструктор A, а в таблице виртуальных функций лежит деструктор B
Почему я делаю виртуальным деструктор A, а в таблице виртуальных функций лежит деструктор B?

Виртуальный деструктор
Здравствуйте! Читаю книжку &quot;Qt 4.5&quot; Макс Шлее (кстати интересно, новичкам рекомендую). Дочитал до чтения/записи параметров программы. Там...

Виртуальный деструктор
Добрый день. Появился вопрос: насколько мне известно, виртуальный деструктор нужно использовать только в тех классах, в которых есть...

27
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13218 / 6850 / 1826
Регистрация: 18.10.2014
Сообщений: 17,374
12.02.2022, 00:32
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Folian Посмотреть сообщение
Для убедительности мне удалось всё хорошенько сломать
Для какой "убедительности"? Какое это все имеет отношение к теме? У delete[] в принципе не бывает полиморфного удаления. Какие там в классе деструкторы - не важно.

В теме речь шла о delete, а не о delete[]. Откуда вдруг взялось delete[] и при чем оно здесь?
1
Неэпический
 Аватар для Croessmah
18150 / 10732 / 2067
Регистрация: 27.09.2012
Сообщений: 27,047
Записей в блоге: 1
12.02.2022, 00:37
Цитата Сообщение от Folian Посмотреть сообщение
Для убедительности мне удалось всё хорошенько сломать
Это неопределенное поведение. Что именно Вы сломали?

Цитата Сообщение от https://eel.is/c++draft/expr.delete#2
In a single-object delete expression, the value of the operand of delete may be a null pointer value, a pointer value that resulted from a previous non-array new-expression, or a pointer to a base class subobject of an object created by such a new-expression. If not, the behavior is undefined. In an array delete expression, the value of the operand of delete may be a null pointer value or a pointer value that resulted from a previous array new-expression. If not, the behavior is undefined.
1
Гвоздь Задиров
 Аватар для Folian
1719 / 1118 / 337
Регистрация: 25.01.2019
Сообщений: 2,946
12.02.2022, 01:05
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Для какой "убедительности"?
Я убедился что левой ерундой заниматься не стоит, это в продолжение мысли из сообщ.18

Цитата Сообщение от Croessmah Посмотреть сообщение
Это неопределенное поведение. Что именно Вы сломали?
Оно просто красиво "не работает" глубокого смысла тут нет.

...

А!! Т.е. A* x { new B[n] } - так же вообще нельзя ? Понятно, т.е. я ещё более левую фигню сотворил. Всё, спать пора значит.

Добавлено через 4 минуты
Цитата Сообщение от Folian Посмотреть сообщение
A* x { new B[n] }
C++
1
A** c { new A*[3] };
Ну конечно!!
К векторам быстро привыкаешь
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13218 / 6850 / 1826
Регистрация: 18.10.2014
Сообщений: 17,374
12.02.2022, 01:24
Цитата Сообщение от Folian Посмотреть сообщение
А!! Т.е. A* x { new B[n] } - так же вообще нельзя ?
Почему "нельзя"? Это-то можно. Но пользы от этого практически никакой и delete[] x потом нельзя.
1
Гвоздь Задиров
 Аватар для Folian
1719 / 1118 / 337
Регистрация: 25.01.2019
Сообщений: 2,946
12.02.2022, 01:39
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Но пользы от этого практически никакой и delete[] x потом нельзя.
Вот и вышла ерунда.

Хотел несколько штук, но забыл как. My bad.
0
677 / 479 / 216
Регистрация: 06.09.2013
Сообщений: 1,312
12.02.2022, 04:26
Может немного и не в тему, но недавно случайно обнаружил, что при некоторых вариантах использования shared_ptr, виртуальный деструктор и не слишком нужен. Как я понимаю за счет стирания типа, объект-deleter из shared_ptr на производный класс перемещается в shared_ptr на базовый класс. С unique_ptr такое не пройдет, там тип deleter-а входит в тип указателя.

Кликните здесь для просмотра всего текста

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
26
27
28
29
30
#include <iostream>
#include <memory>
 
struct A {
    ~A(){
        std::cout << "~A" << std::endl;
    }
};
 
struct B : public A {
    ~B(){
        std::cout << "~B" << std::endl;
    }
};
 
std::shared_ptr<A> make_shared_B() {
    return std::make_shared<B>();
}
 
std::unique_ptr<A> make_unique_B() {
    return std::make_unique<B>();
}
 
int main()
{    
    std::cout << "shared_ptr:" << std::endl;
    { auto s = make_shared_B(); } 
    std::cout << "unique_ptr:" << std::endl;
    { auto u = make_unique_B(); }
}
Code
1
2
3
4
5
shared_ptr:
~B
~A
unique_ptr:
~A
0
Неэпический
 Аватар для Croessmah
18150 / 10732 / 2067
Регистрация: 27.09.2012
Сообщений: 27,047
Записей в блоге: 1
12.02.2022, 13:20
Цитата Сообщение от woldemas Посмотреть сообщение
Как я понимаю за счет стирания типа, объект-deleter из shared_ptr на производный класс перемещается в shared_ptr на базовый класс.
У них общий разделяемый блок, так что ничего никуда перемещать не надо.
Закончились ссылки - дернули deleter.
0
677 / 479 / 216
Регистрация: 06.09.2013
Сообщений: 1,312
12.02.2022, 13:59
Цитата Сообщение от Croessmah Посмотреть сообщение
У них общий разделяемый блок
Наверное, я не большой эксперт.
Просто поначалу думал, что без виртуального деструктора тоже корректно работать не будет. А тут получается, указатель как бы помнит тип объекта.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
12.02.2022, 13:59

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

виртуальный деструктор
есть такой пример, у меня вопрос, почему здесь деструктор декларирован просто как деструктор, а не виртуальный (и является ли он в данном...

Наследование и виртуальный деструктор
Здравствуйте. Есть такая иерархия классов: https://ibb.co/dtJL2B5 В MorphingLayer и MorphDecorator деструкторы объявлены как...

Виртуальный деструктор на MinGW v4.9.2
не знаю как на прошлых версиях, но на этой не работает чисто виртуальный деструктор. проверялось самым обычным тестом class A{ ...

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


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

Или воспользуйтесь поиском по форуму:
28
Ответ Создать тему
Новые блоги и статьи
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами: - ВидТО (СправочникСсылка. ВидыТО); - ВидГСМ. . .
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 30.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
Оттачиваю умение писать js программы.
russiannick 30.08.2026
Проектом выходного дня стало написание Книги шифров Виженера. Итогом стала версия 200, синий туман. Синий туман назван так, потому что замораживает текст под собой. Нажатие синих кнопок управляют. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru