Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.82/11: Рейтинг темы: голосов - 11, средняя оценка - 4.82
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602

Виртуальные методы без деструкторов

07.08.2019, 06:03. Показов 2986. Ответов 34
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Знаю что хочу странного, но все же. Можно ли как-то объявить класс с виртуальными методами. но без деструктора и чтоб компилятор не плевался варнингами? Средствами языка, а не отключив варнинги в компиляторе.

Предупреждая вопрос нафиг надо - хочу выделять память из пула, а потом вместо удаления отдельных объектов, грохнуть сам пул. Разумеется, чтобы это сделать, нужно чтобы все объекты были trivially destructible. А для этого у них не должно быть никакого деструктора.

Предупреждая возражение "а вдруг случайно какому-то потомку не тривиальный деструктор добавишь" - а я static_assert подопру.
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
31
32
33
34
35
//'Parent' has virtual functions but non-virtual destructor
class Parent
{
public:
    virtual void method(){}
};
 
class FirstChild:public Parent{};
class SecondChild:public Parent{};
 
union AnyChild
{
    AnyChild(){}
 
    FirstChild firstChild;
    SecondChild secondCHild;
};
 
template<typename T>
T*create(void*mem)
{
    static_assert (std::is_trivially_destructible<T>::value);
    return new (mem) T;
}
 
int main()
{
    AnyChild*pool=new AnyChild[100];
    //создание объектов
    create<FirstChild>(pool);
    create<SecondChild>(pool+1);
    //удаление пула
    delete[] pool;
    return 0;
}
1
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
07.08.2019, 06:03
Ответы с готовыми решениями:

Виртуальные методы
народ вот пример с виртуальными методами, и вывод этой программы class Ancestor { public: virtual void function1 () { cout...

Виртуальные методы
Здраствуйте , вот писал виртуальный метод доступа но почему то не получаеться , подскажите почему ??? заранее спасибо ...

Виртуальные методы
Всем доброго времени суток! Вопрос следующий. Как я могу функцией делать подмену виртуального метода у класса?

34
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
07.08.2019, 19:52
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Renji Посмотреть сообщение
Закоментировал virtual. Чуда не случилось, оба раза вызвался базовый метод.
Это нормально.
Я просил все ///////// закомментить - уничтожить завещание убрать наследование как факт последнего волеизъявления)

Добавлено через 1 минуту
Цитата Сообщение от Renji Посмотреть сообщение
Где ищет? Нет virtual->нет таблицы в которой искать виртуальный метод.
Компилировали? ВТБ там нету уже, - правильно.
0
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
07.08.2019, 19:52  [ТС]
Цитата Сообщение от IGPIGP Посмотреть сообщение
Я просил все ///////// закомментить
Так по ссылке вроде и все остальное в комментариях.

Добавлено через 36 секунд
Цитата Сообщение от IGPIGP Посмотреть сообщение
Компилировали? ВТБ там нету уже, - правильно.
Ну да, на rextester.com компилировал.
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
07.08.2019, 19:54
Цитата Сообщение от Renji Посмотреть сообщение
Ну да, на rextester.com компилировал.
И не работает?
0
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
07.08.2019, 19:55  [ТС]
Цитата Сообщение от IGPIGP Посмотреть сообщение
И не работает?
Показывает
fooBase

fooBase
внизу страницы. То есть, вызван дважды один и тот же базовый метод.
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
07.08.2019, 19:57
Думаю вы неровно закомментил. Вот так я хотел:
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include<iostream>
using namespace std;
 
struct BaseNoDestructable
{   
    BaseNoDestructable() {};
    //virtual ///////
        void foo() { cout << "\nfooBase\n"; }
    //~BaseNoDestructable() = delete;//если не закомментировать - ошибка - ссылка на удалённую функцию  
};
 
struct ChildNoDestructable
    //:public BaseNoDestructable////////
{   
    ChildNoDestructable() 
        //:BaseNoDestructable()//////////
    {};
 
        void foo() { cout << "\nfooChild\n"; }
 
    //~ChildNoDestructable() = delete;
 
};
 
 
void TestThatMuck()
{
    const size_t pool_obj_len = 2;
    unsigned char *pool=new unsigned char[sizeof(BaseNoDestructable) * pool_obj_len];
    
    BaseNoDestructable* startObjPtr = reinterpret_cast<BaseNoDestructable*>(pool);
    new(startObjPtr)BaseNoDestructable();
    new(++startObjPtr)ChildNoDestructable();
    --startObjPtr;
    startObjPtr->foo();
    ++startObjPtr;
    startObjPtr->foo();
    delete[] pool;
 
}
 
int main()
{   
    TestThatMuck();
    return 0;
}
Добавлено через 48 секунд
Цитата Сообщение от Renji Посмотреть сообщение
То есть, вызван дважды один и тот же базовый метод.
Просто скопируйте последний текст и скажите потом, кто кого вызвал.
0
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
07.08.2019, 19:59  [ТС]
Цитата Сообщение от IGPIGP Посмотреть сообщение
Просто скопируйте последний текст и скажите потом, кто кого вызвал.
Тоже самое "fooBase fooBase".
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
07.08.2019, 20:10
Цитата Сообщение от Renji Посмотреть сообщение
"fooBase fooBase".

Вы правы. Я напутал что-то. Стало быть вопрос о наследовании - моя ошибка. Значит без наследования не прокатит.
Пардон - Не пойму куда смотрел!
И знаю ведь, что вызов по указателю (без vtable) вообще не зависит от адреса, - только от типа. А от адреса может зависеть корректность контекста и соответственно возможность креша. То есть можно и
C++
1
2
BaseNoDestructable *nullPtrCall = nullptr;
    nullPtrCall->foo();
Так что не прав я.
А как на счёт того что delete для базового не компилируется?
0
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
07.08.2019, 20:14  [ТС]
Цитата Сообщение от IGPIGP Посмотреть сообщение
А как на счёт того что delete для базового не компилируется?
Компилируется, только опять же плюется варнингами.
Но как и сказано в стартпосте, удалять объекты по одному через delete и не планируется. так что void operator delete(void*)=delete и все.
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
07.08.2019, 20:21
Цитата Сообщение от Renji Посмотреть сообщение
Компилируется, только опять же плюется варнингами.
Я сейчас на mvs19 бесплатной (ключи по умолчанию, не трогал) и не компилит с наследованием, - раскомментируйте все /////// и строчку с delete - деструктору базового класса.

Добавлено через 2 минуты
Ошибка C2280 "BaseNoDestructable::~BaseNoDestructable (void)": предпринята попытка ссылки на удаленную функцию console_empty ...\main.cpp
0
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
07.08.2019, 20:24  [ТС]
Цитата Сообщение от IGPIGP Посмотреть сообщение
Я сейчас на mvs19 бесплатной (ключи по умолчанию, не трогал) и не компилит с наследованием, - раскомментируйте все /////// и строчку с delete - деструктору базового класса.
В gcc норм, так что, видимо, от компилятора зависит. В любом случае это не проблема, так как delete, повторюсь, использовать и не планировалось.
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
07.08.2019, 20:32
Цитата Сообщение от Renji Посмотреть сообщение
В gcc норм, так что, видимо, от компилятора зависит. В любом случае это не проблема, так как delete, повторюсь, использовать и не планировалось.
MinGW G++
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include<iostream>
using namespace std;
 
struct BaseNoDestructable
{   
    BaseNoDestructable() {};
    virtual ///////
        void foo() { cout << "\nfooBase\n"; }
    ~BaseNoDestructable() = delete;//если не закомментировать - ошибка - ссылка на удалённую функцию    
};
 
struct ChildNoDestructable
    :public BaseNoDestructable////////
{   
    ChildNoDestructable() 
        :BaseNoDestructable()//////////
    {};
 
        void foo() { cout << "\nfooChild\n"; }
 
    ~ChildNoDestructable() = delete;
 
};
 
 
void TestThatMuck()
{
    const size_t pool_obj_len = 2;
    unsigned char *pool=new unsigned char[sizeof(BaseNoDestructable) * pool_obj_len];
    
    BaseNoDestructable* startObjPtr = reinterpret_cast<BaseNoDestructable*>(pool);
    new(startObjPtr)BaseNoDestructable();
    new(++startObjPtr)ChildNoDestructable();
    --startObjPtr;
    startObjPtr->foo();
    ++startObjPtr;
    startObjPtr->foo();
    delete[] pool;
 
 
 
}
 
int main()
{   
    TestThatMuck();
    
    return 0;
}
...\ConsoleCppTest\main.cpp|809|error: use of deleted function 'BaseNoDestructable::~BaseNoDestructable ()'|

Добавлено через 1 минуту
Цитата Сообщение от Renji Посмотреть сообщение
В любом случае это не проблема, так как delete, повторюсь, использовать и не планировалось.
Я же об этом и говорю, - в коде нет запуска деструктора ни через delete ни как ещё.
0
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
07.08.2019, 20:39  [ТС]
Цитата Сообщение от IGPIGP Посмотреть сообщение
Я же об этом и говорю, - в коде нет запуска деструктора ни через delete ни как ещё.
В стартпосте же написано, объекты trivially destructible. Ради этого все и задумано. "Objects with trivial destructors don't require a delete-expression and may be disposed of by simply deallocating their storage."
Цитата Сообщение от IGPIGP Посмотреть сообщение
MinGW G++
Ну так не надо объявлять не тривиальный деструктор и тут же помечать его delete.
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
07.08.2019, 21:31
Цитата Сообщение от Renji Посмотреть сообщение
Ну так не надо объявлять не тривиальный деструктор и тут же помечать его delete.
Я бы с удовольствием посмотрел что есть тривиальный деструктор. Пока нашел, что деструктор не должен быть виртуальным, базовый класс и члены должны иметь тривиальные деструктора, но это рекурсия. Непонятно что такое нетривиальный деструктор.
А про G++ я написал, потому что вы говорите, что оно с варнингом, компилится. Не компилится.
Renji, я пытаюсь смоделировать ситуацию:
Цитата Сообщение от Renji Посмотреть сообщение
о у них не должно быть никакого деструктора
Деструктор по умолчанию не укладывается в это условие, потому, что он генерится компилятором.
0
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
07.08.2019, 21:43  [ТС]
Цитата Сообщение от IGPIGP Посмотреть сообщение
Я бы с удовольствием посмотрел что есть тривиальный деструктор. Пока нашел, что деструктор не должен быть виртуальным, базовый класс и члены должны иметь тривиальные деструктора, но это рекурсия.
Ну да, рекурсия.
Деструктор не задан пользователем (not user-provided).
Деструктор не виртуальный.
Если есть базовые классы и члены класса, для них условия выше применяются рекурсивно.
Кратко говоря, ни один из образующих объект классов не должен иметь явно прописанного деструктора. Тогда его можно прибить через сишный free, даже если там виртуальные методы.
Цитата Сообщение от IGPIGP Посмотреть сообщение
А про G++ я написал, потому что вы говорите, что оно с варнингом, компилится. Не компилится.
C++
1
2
3
4
5
6
7
8
9
10
11
12
class Parent
{
public:
    virtual void method(){}
};
 
int main()
{
    auto value=new Parent;
    delete value;//deleting object of polymorphic class type ‘Parent’ which has non-virtual destructor might cause undefined behavior
    return 0;
}
1
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
07.08.2019, 23:27
Пример не о том. За разъяснение - спасибо. То есть, явно объявленный деструктор - уже не тривиален. Как-то странно слова сцеплены. Но раз так написано, - нужно блюсти. Пути стандарта неисповедимы.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
07.08.2019, 23:27

виртуальные методы
как вызвать виртуальный метод базового класса из наследуемого класса? struct A { virtual void vf() { printf(&quot;A&quot;); ...

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

Виртуальные методы
Дан родительский класс Animal (поле кличка). И два наследованных от него класса-потомка: Cat (поле рост - h), Dog(поле рост - h)....

виртуальные методы
#include&lt;iostream&gt; #include&lt;stdlib.h&gt; using namespace std; class MArray { protected: static const int MAX=512; ...

Наследование и виртуальные методы
В описании задания буквой А) обозначается задание на базовый класс, а буквой Б) - на класс наследник, или класс, использующий класс А как...


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

Или воспользуйтесь поиском по форуму:
35
Ответ Создать тему
Новые блоги и статьи
Книги по геймдизайну, левел-дизайну, игровым механикам и проектированию игрового опыта
8Observer8 08.11.2026
Содержание блога | English Version 1. 2003 - 06 - Designing Virtual Worlds (1st Edition) Автор: Richard A. Bartle | Объем: 768 стр. Ссылки: Amazon . . .
Родители токсичные абьюзеры по отношению к своим детям ругают их оскорбляют не любят
zorxor 08.11.2026
Жить в атмосфере постоянных оскорблений, критики и холодности со стороны родителей — это тяжелое и болезненное испытание, которое оставляет глубокие эмоциональные раны. Токсичное и абьюзивное. . .
Как только я захожу к себе в свою комнату я сразу же с себя снимаю свои трусы. Ответ от Джемени ИИ.
zorxor 08.11.2026
Джемени, как только я захожу к себе в свою комнату я сразу же с себя снимаю свои трусы. Многие люди, возвращаясь домой, сразу переодеваются в максимально свободную одежду или вовсе предпочитают. . .
Паттерн очереди действий/команд (Action / Command Queue). Система очереди действий и кат-сцен с SDL3 Callbacks, cglm и OpenGL
8Observer8 07.11.2026
Содержание блога | English Version Руководство для начинающих по реализации паттерна очереди действий/ команд (Action / Command Queue) на C++ (C++20) с использованием официального SDL3 Callbacks. . .
Проверка полного ФИО в типовом справочнике
Maks 07.11.2026
Решение реализовано в конфигурации КА2, на примере справочника "КонтактныеЛицаПартнеров". Задача: Запрет инициалов. Не допускаеть использование сокращений вида "И. И. ", "И. И. ", "И И" и. . .
Про "Windows must die!"
kumehtar 04.11.2026
Знаете, чет накатило. . . . Когда-то это было почти боевым кличем: мол, нормальный человек сидит на DOS, OS/ 2 или Linux, а вот это вот - Must Die. А теперь человек произносит «мастдай» с усмешкой - и. . .
Красочные поля с номером страницы svg+background-image
russiannick 04.11.2026
Красочные поля с номером страницы не менее важны чем в эпоху бумажных книг. Посему спешу представить почтеннейшей публике этот важный инструмент который эти поля и формирует. В процессе разработки. . .
Вступаем в новую фазу генерации favicons, векторную.
russiannick 02.11.2026
Теперь нет нужды скрывать что используется простой svg. Исходный код изображения помещаем в поле и жмем кнопку. Исходник преобразуется в вид корректный для помещения в favicon или в url(). Нажатие. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru