170 похожих чатов

#Include <iostream> using std::cout; using std::cin; using std::endl; class A { public: virtual

~A() { cout << "Hello from A\n"; }
};

class B : virtual public A
{
public:
~B() override { cout << "Greeting from B\n"; }
};

class D : public B
{
public:
~D() override { cout << "Greeting from D\n"; }
};

int main()
{
A* d = new D;
delete d;
d = nullptr;
return 0;
}

как то можно сделать так, чтобы деструктор базового класса не унаследовался виртуально для деструктора класса D?

65 ответов

82 просмотра

можно: не наследуйте D от базового класса

Sasha- Автор вопроса

ключевое слово НЕ виртуально, то есть мне нужно обычное наследование именно для D

Деструктор базового класса и так наследуется невиртуально.

Sasha
ключевое слово НЕ виртуально, то есть мне нужно об...

(прочиал UPD) вы хотите чтобы у объекта с динамическим типом D НЕ вызывался деструктор от типа D?

Sasha- Автор вопроса
Ilya Zviagin
Деструктор базового класса и так наследуется невир...

хорошо, давайте другой пример с Show #include <iostream> using std::cout; using std::cin; using std::endl; class A { public: virtual void Show() { cout << "Hello from A\n"; } }; class B : public A { public: void Show() override { cout << "Greeting from B\n"; } }; class D : public B { public: void Show() override { cout << "Greeting from D\n"; } }; int main() { A* d = new D; d->Show(); return 0; }

Sasha
хорошо, давайте другой пример с Show #include <io...

И ? Только быстрее, а то я спать уйду

Sasha- Автор вопроса
Sasha- Автор вопроса
Sasha
хочу чтобы вызвался Show из B

так, всё, пора спрашивать то, что я не люблю спрашивать: ЗАЧЕМ?

Sasha
хочу чтобы вызвался Show из B

Нет проблем! class D : public B { public: void Show() override { B::Show(); } };

Sasha- Автор вопроса
Ilya Zviagin
Что вызывалось ?

здесь метод Show виртуально унаследовался?

Ilya Zviagin
И ? Только быстрее, а то я спать уйду

хочу понаписать наследования с virtual'ами, но чтобы работало как без virtual'ов и без наследования

Sasha
здесь метод Show виртуально унаследовался?

Такого не бывает. Методы наслеюуются или нет, и бывают виртуальными или нет

Гражданин Котейко
хочу понаписать наследования с virtual'ами, но что...

тогда надо не делать virtual и не наследоваться !

Sasha- Автор вопроса
Ilya Zviagin
Такого не бывает. Методы наслеюуются или нет, и бы...

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

Sasha
здесь метод Show виртуально унаследовался?

Да, он в базовом объявлен виртуальным, будет везде виртуальным

Sasha
хочу чтобы вызвался Show из B

Я не очень понимаю в виртуальном этом всем, но думаю, для того что ты хочешь надо просто в классе D не определять метод show. (но я не уверен)

Sasha
ну вот здесь он виртуально унаследовался, верно? у...

Нельзя метод унаследовать виртуально или нет. Методы просто наследуются или нет, и могут быть виртуальными или нет.

Ilya Zviagin
Нельзя метод унаследовать виртуально или нет. Мето...

тут явно заявка на пропозал на киллерфичу для C++29

Sasha
ну вот здесь он виртуально унаследовался, верно? у...

Он ВЫЗЫВАЕТСЯ виртуально, а не наследуется.

Ilya Zviagin
Нельзя метод унаследовать виртуально или нет. Мето...

Не совсем понял твои слова "метод наследуется ИЛИ нет". Я всегда думал, что если в базовом классе есть какой то метод, то в производном он будет по любому. Он всегда наследуется. Другое дело, что если он виртуальный, то ты можешь его переопределить в производном. Или все таки можно как то сделать так, чтоб метод базового вообще по попадал в состав производного? Мне кажется так нельзя

Sasha- Автор вопроса
Ilya Zviagin
Он ВЫЗЫВАЕТСЯ виртуально, а не наследуется.

ну вот есть class A { public: virtual Show(); } здесь этот метод Show будет ко всей цепочке унаследованных классов являться virtual?

Sasha
ну вот есть class A { public: virtual Show(); ...

Да. По другому не бывает

Понял. Но тогда его можно будет вызвать только через указатель на производный (через базовый нельзя) верно я понимаю?

Sasha- Автор вопроса
Ilya Zviagin
Да. По другому не бывает

ещё раз переспрошу для уверенности, то есть class A { public: virtual void Show(); }; class B : public A { public: void Show(); }; class C : public B { public: void Show(): }; здесь метод Show в классе C никак обычно не унаследовать UPD: чтобы при вызове A* c = new C; c.Show(); вызвался метод класса B, но не C. Просто есть цепочка A->B->C, если метод Show класса С можно как то унаследовать обычно, то тогда по логике должно вызваться Show метода B )))

The Pressbraker
Не совсем понял твои слова "метод наследуется ИЛИ ...

Ну и приватные функции функционально (не технически) не наследуются по понятным причинам.

наследуются

Ilya Zviagin
наследуются

Только технически. Использовать это никак не получится (по крайней мере без очень грязных хаков).

Sasha- Автор вопроса

апдейтнул

Alexander "Ternvein" Isaev
Только технически. Использовать это никак не получ...

Ну тебе компилятор при вызове будет говорить, что метод недоступен. Вот если его ПЕРЕГРУЗИТЬ в наследнике, он скроется.

Sasha
ещё раз переспрошу для уверенности, то есть class...

Я писал выше. Переопределить в C метод Show() и вызвать в нём метод класса B (B::Show). НО c деструкторами такой финт не прокатит, 0) деструктор всегда есть и 1) он всегда будет вызван, 2) и потом будет вызван деструктор базового класса.

Alexander "Ternvein" Isaev
Только технически. Использовать это никак не получ...

https://en.cppreference.com/w/cpp/memory/memory_resource (обратите внимание на приватные виртуалы)

Гражданин Котейко
https://en.cppreference.com/w/cpp/memory/memory_re...

Я знаю эту шляпу, но не одобряю. Они должны быть protected.

Alexander "Ternvein" Isaev
Я знаю эту шляпу, но не одобряю. Они должны быть p...

не, не должны, по исходной задумке их только база из невиртуального интерфейса дёргает

Sasha- Автор вопроса
Ilya Zviagin
Деструктор базового класса и так наследуется невир...

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

Sasha
да, но только, если будет вызван через свой же ука...

Все так: как и для любого другого невиртуального метода. В отличие от них, впрочем, деструктор производного класса, в случае если базовый объявлен виртуальным, не заменит, а дополнит порядок разрушения объекта. Т.е.: struct B { virtual void f ( ); virtual ~B ( ); }; struct D: B { void f ( ) override; ~D ( ) override; }; int main ( ) { B* b{new D}; b->f() /* #1 */; delete b /* #2 */; } В #1 вызовется D::f(), но в #2 вызовется D::~D(), после чего B::~B().

Sasha- Автор вопроса
Sasha- Автор вопроса
Sergey Anisimov
Все так: как и для любого другого невиртуального м...

это да, а если ну будет виртуального наследования, то вызовется в этом случае только деструктор структуры B

Sasha
что это за конструкция {new D}?

Скорее b{}: это один из синтаксисов инициализации. В разных ситуациях (не)возможно использование в этих целях =, () или {} (как здесь). new D - выражение, создающее объект типа D с dynamic-storage-duration (объект, управление временем жизни которого осуществляется вручную и может производиться во время выполнения).

Sasha
это да, а если ну будет виртуального наследования,...

Если точнее, в этом случае будет неопределенное поведение (программа содержит недиагностируемую фатальную ошибку, последствия (даже неизбежного достижения в будущем которой) которой формально непредсказуемы).

Sasha- Автор вопроса
Sasha
у меня твой код не комплится)

Скорее всего потому, что под "не компилится" Вы понимаете "не компонуется": он и не может, поскольку определения для всех используемых функций в примере отсутствуют (они для него не нужны). Если хотите его собрать - замените все точки с запятыми в пределах определений структур на пары фигурных скобок.

Sasha- Автор вопроса
Sasha- Автор вопроса
Sergey Anisimov
Скорее всего потому, что под "не компилится" Вы по...

а с чего вы взяли, что это компоновка а не компиляция? я так почитал, что такое компоновка и как для себя понял, компилятор сначала преобразует всё в машинный код, затем в обьекты, а компоновкщик обьединяет это всё

Sasha
а с чего вы взяли, что это компоновка а не компиля...

Компилятор работает в пределах контекста единицы трансляции. Он как раз свою работу способен выполнять и без доступа к определениям функций в том примере.

Sergey Anisimov
Все так: как и для любого другого невиртуального м...

Ребят, не могли бы Вы поделиться источниками по которым Вы изучали ООП? Всё что я видел либо поверхностное, либо не разбирает подобных махинаций

Pasha Kryvulets
Ребят, не могли бы Вы поделиться источниками по ко...

Непосредственно к ООП это отношения не имеет; это про работу языка. Помимо каких-то преимущественно базовых представлений, конкретно я свои отсюда и отсюда получал. Первое - справочник по языку, второе - актуальный черновик спецификация языка. Насколько такой подход можно рекомендовать - не подскажу.

Sasha
что это за конструкция {new D}?

uniform инициализация адресом, который возвращает оператор new.

Sasha- Автор вопроса

а в чем её прикол, или это просто как фишка?

Sasha
а в чем её прикол, или это просто как фишка?

Как по мне, это универсальный способ инициализации и присваивания переменных, массивов и объектов.

Pasha Kryvulets
Ребят, не могли бы Вы поделиться источниками по ко...

Да разбирает. Просто надо вдумываться. В лбом учебнике по с++ это есть, Липпман например, или Детей Детей.

Sasha
ключевое слово НЕ виртуально, то есть мне нужно об...

Ты не можешь проигнорировать и обойти деструктор базового класса. Он все равно будет выполнен.

Похожие вопросы

Обсуждают сегодня

а зачем этот вопрос для удаления из чата?
Mёdkinson Medvezhkin
63
Эх кто-то пришел и весь праздник испортил :( You need complex FBX scene importing setup to change things on import? good luck with that. You need navigation and pathfinding? g...
Serg Gini
5
Всем привет! Подскажите. Я написал приложение на Delphi 10.2 Tokyo под Windows 10. И передо мной стал вопрос о том чтобы сделать это приложение кроссплатформенным (под Linux и...
Дмитрий Завгородний
24
Какого хера? /Sources/App/Modules/User/Models/UserLinkApple.swift:21:20: warning: stored property '_id' of 'Sendable'-conforming class 'UserLinkApple' is mutable @ID(...
Alexander Sherbakov
14
Привет всем. Подскажите где можно посмотреть, какая версия электрон, поддерживает версии windows? Некий changelog. Мне бы желательно, поддержку 7,8,10... latest, как понимаю и...
Anonym Squad
21
Почему стало ломаться на D11? "739002.86400000' is not a valid timestamp" function IncDateTime(aStamp:TTimeStamp;aKind:TTriggerKind;aInterval:Integer):TDateTime; //aStamp = 2...
Катерина Свиридова
8
У тебя в конфиге нигде нет deny all; или вообще любого deny?
Alexander Sherbakov
10
Портфолио: Зовут меня Александр, мне 36 лет. Город Пушкино. Общий рабочий стаж: ~14 лет Уровень квалификации: Senior Full-stack developer Где прочесть мой код? https://github....
Magic
10
Есть ли смысл устраиваться на 1с ? Даст это плюс в дальнейшем трудоустройстве на php? Просто у меня в городе вакансий на пхп нету. Или лучше удаленно искать. Опыта работы нету...
Azamat
14
Ребят, чет я уже не догоняю... Крч в коде на асм там происходит нечто вроде a+число (a+1, a+2 и т.д.). Но почему строка lea ecx, [edx+1] работает как a+1?? В edx берется адрес...
Alan 🔝 Бэброу
4
Карта сайта