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

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

11.02.2022, 23:24. Показов 2489. Ответов 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
13210 / 6843 / 1824
Регистрация: 18.10.2014
Сообщений: 17,308
12.02.2022, 00:32
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Folian Посмотреть сообщение
Для убедительности мне удалось всё хорошенько сломать
Для какой "убедительности"? Какое это все имеет отношение к теме? У delete[] в принципе не бывает полиморфного удаления. Какие там в классе деструкторы - не важно.

В теме речь шла о delete, а не о delete[]. Откуда вдруг взялось delete[] и при чем оно здесь?
1
Неэпический
 Аватар для Croessmah
18149 / 10731 / 2067
Регистрация: 27.09.2012
Сообщений: 27,038
Записей в блоге: 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
13210 / 6843 / 1824
Регистрация: 18.10.2014
Сообщений: 17,308
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
18149 / 10731 / 2067
Регистрация: 27.09.2012
Сообщений: 27,038
Записей в блоге: 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
Ответ Создать тему
Новые блоги и статьи
тв 16 бой ии
anaschu 27.07.2026
Великий Перелом ИИ: Как уравнения ОДУ Radau дожали цензурные фильтры Алисы Фиксируем в мемофонде Теории Всего беспрецедентный факт в истории ИИ-зондирования. В затяжном многораундовом. . .
мв 15. непроверенное, возможно, глюк
anaschu 27.07.2026
НАУЧНО-АНАЛИТИЧЕСКИЙ ОТЧЕТ. РАЗДЕЛ 1. 1: «НАУКА» (РАСШИРЕННАЯ СТЕХИОМЕТРИЧЕСКАЯ И ГЕНЕТИЧЕСКАЯ ВЕРСИЯ)Тема: Теоретическое обоснование инвариантности 19-мерного тензорного ядра непрерывных ОДУ и. . .
Очистка реквизитов и табличных частей документа при копировании
Maks 26.07.2026
Алгоритм из решения ниже разработан на примере нетипового документа "ЗаявкаНаРаботу", разработанного в КА2. Задача: Заменить алгоритм запрета копирования документов для сотрудников с ролью "Стажер",. . .
Доктрина интенционального знания - Доктрина для портала "Срез".
Hrethgir 25.07.2026
Может найдётся кто захочет оценить доктрину. . . Написания правил участия для меня роскошь, требующая лимита времени, поэтому все сообщения не прошедшие модерацию будут видны только участникам портала,. . .
сукцессия 44. Решил подать на припринт в межународные сервисы препринтов. Но нужно одобрение от ученых
anaschu 25.07.2026
Английский вариант. Пока кто то не одобрит мою личность, мне не получиться это опубликовать на препринте. Но заявку на публикацию статьи я сегодня подам.
сукцессия 43. Вторая научная статья за месяц- прайминг и гатгил
anaschu 25.07.2026
две стороны одной монеты
Более приземисто - Эстафету хвоста в .cdl (деревья эстафеты в сад).
Hrethgir 24.07.2026
В будущем, после написания блока инверсии обхода дерева (эстафеты хвоста), я планирую вернуться к нашему прошлому разговору о том, обладают ли знания целеполаганием. Тогда я пришел к выводу, что. . .
Вот представьте что вам дали бессмертие.
kumehtar 24.07.2026
Вот представьте что вам дали бессмертие, ничего более не меняя. Вообще ничего, только бессмертие в нынешнем виде. Рады были бы? Что бы вы тут делали всё это время? Никакой пенсии. Никакого нового. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru