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 ответов

94 просмотра

можно: не наследуйте 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
ключевое слово НЕ виртуально, то есть мне нужно об...

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

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

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

Anyone here suffers from unexplained aural migraines, who would be up for talking for a bit? Doesn't *have* to be aural, but I am not asking about headaches, I mean actual mi...
Martin Rys
55
Я тут за тем, чтобы задать вопрос, так как не знаю ассемблер, учу с/с++. Короче, насколько дорога операция перехода в функцию при ее вызове? Дело в том, что в с++ есть макросы...
Максим Рябцев
12
А какие чаты вообще в ходу? Auto aim? И что еше
do you think you're better off alone? А
13
Привет, нужен совет старших товарищей. Есть глобальная переменная var DefaultDataFolder:string; инициализируем DefaultDataFolder:='a:\_OUT\'; есть примитивная процедур...
Max Otto
14
hello friends. Do you know how can I learn getx? I have a software project that I should deliver it up to 5 weeks later and I need to learn firebase too. I will be thankfull
AmirHossein Razavi
15
Доброе время суток! у меня тут иноды закончились. и понял почему по сути кстит, я периодически очищаю постгрес и сентри контайнер: postgres=# DELETE FROM nodestore_node WHER...
Юсиф Насиров
9
Вопрос. Теоретический. Есть список команд. Команды отправляю в обработку некой функции, по очереди. Разные команды могут давать разные результаты после обработки. В зависимос...
Serjone
7
lazarus-3.2.0/gtk, linux патч "имя проекта по умолчанию project1 -> prj" день добрый не нравится "именя проекта по умолчанию" (project1), к.раз приходится переименовывать (н...
livontiy
5
Какой дос блять?
007
9
Коллеги, а в чём сейчас хорошо писать на перле, в смысле ide? Пробовал в идее с плагином, подсветка есть, даже какие-то предупреждения есть, но рефакторинга считай нет. Перене...
Дмитрий Петров
9
Карта сайта