+3
- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
#include <iostream>
using namespace std;
class Base {
public:
Base() {
cout << "Base construct\n";
}
virtual ~Base() {
cout << "Base destruct\n";
}
};
class Child: public Base {
public:
Child() {
cout << "Child construct\n";
}
~Child() {
cout << "Child destruct\n";
}
};
int main() {
Base *base = new Child();
delete base;
}
Hy нe oчeвиднo жe! Для тoгo, чтoб вызывaлиcь вce дecтpyктopы, нyжнo oбъявить eгo виpтyaльным. B тo вpeмя кaк кoнcтpyктop бeз мoдификaтopa virtual paбoтaeт тaк жe, кaк виpтyaльный дecтpyктop.
И зaчeм вoбщe ocтaвлять вoзмoжнocть нe виpтyaльнoгo дecтpyктopa - нe мoгy пpeдcтaвить ceбe cлyчaя, кoгдa пpи yдaлeнии oбъeктa нyжeн вызoв дecтpyктopa тoлькo бaзoвoгo клacca.
Запостил: Pythoner,
18 Марта 2014
chtulhu 18.03.2014 15:19 # +2
guest 18.03.2014 15:19 # 0
roman-kashitsyn 18.03.2014 15:33 # +5
Т.е. ты не можешь представить себе случай, когда класс не подразумевает наличия наследников? У меня 96.8% классов таких.
Pythoner 18.03.2014 15:44 # 0
roman-kashitsyn 18.03.2014 15:47 # +2
а теперь перечитай ещё раз мой комментарий
Pythoner 18.03.2014 16:09 # −5
Причем тут класс без наследников?
roman-kashitsyn 18.03.2014 16:12 # +3
Если у класса не должно быть наследников, зачем ему может понадобиться виртуальный деструктор?
Правильно, не нужен.
TarasB 18.03.2014 16:14 # 0
Pythoner 18.03.2014 16:20 # 0
TarasB 18.03.2014 17:34 # +1
new Derived - какой вызвал, такой и вызвался
1024-- 18.03.2014 18:33 # −1
> Схуялли он ведёт себя как виртуальный?
1. Наблюдатель удаляет объект хрен знает какого класса, имея указатель на объект класса родителя - вызывается только деструктор родителя.
2. Наблюдатель добавляет слово virtual к деструктору - вызываются деструкторы [b]потомков[b] и деструктор родителя.
3. Наблюдатель делает вывод: "виртуальный %X%", при вызове которого вызывается не только %X% потомка, но и %X% родителя.
4. Наблюдатель создаёт объект - вызываются конструктор родителя и конструкторы потомков.
5. С точки зрения наблюдателя конструктор - виртуальный.
UPD: Тьфу, автор уже описал этот мысленный эксперимент, но менее подробно в http://govnokod.ru/15517#comment221649. И я же читал тот комментарий...
roman-kashitsyn 18.03.2014 19:47 # +2
1024-- 18.03.2014 18:53 # 0
Что будет плохого, если объявить все деструкторы виртуальными, а там, где на стадии компиляции ясно, какой класс, не лезть в таблицу и вызывать сразу нужные деструкторы?
roman-kashitsyn 18.03.2014 19:03 # +3
Ну и это нарушает один из основопологающих принципов плюсов - не платить за то, что не используешь.
> там, где на стадии компиляции ясно, какой класс, не лезть в таблицу и вызывать сразу нужные деструкторы?
Это оптимизация уже давно работает для всех виртуальных функций (и деструкторов). Если компилятору точно известен тип, виртуальные функции вызываются невиртуально.
1024-- 18.03.2014 19:27 # 0
Не подумал об этом. А для оптимизации (удаления лишнего поля) уже потребуется перекомпилировать класс-родитель, печаль.
TarasB 18.03.2014 19:49 # 0
А для динамического полиморфизма подойдёт сахар-динамитор, что-то типа более удобного tagged union.
roman-kashitsyn 19.03.2014 08:37 # 0
В теории можно было сказать "пусть деструктор будет виртуальным только у типов, объявленных с ключевым словом class", но это уже попахивает Д.
bormand 19.03.2014 09:38 # 0
Да и лейаут оно не испортит, если не забывать каст (который в данном случае уже не nop).
roman-kashitsyn 19.03.2014 09:49 # +2
Опять же, как отличить структуру, от которой мы хотим иметь возможность наследоваться, от старой доброй сишной? Если POD - нет виртуального деструктора, если не POD - есть?
Я за явный virtual для деструктора, explicit is better than implicit. В крестах и так слишком много сложностей на ровном месте.
bormand 19.03.2014 09:59 # 0
Слово struct оставить для POD'ов, полностью запретив в них виртуальные методы, динамик каст, множественное наследование и наследование от не POD'ов.
Слово class оставить для настоящих классов, у которых виртуальный деструктор и ТВМ никак не убираются. И запретить наследовать class от struct, ибо нехрен.
> добавить к стуктурке удобных методов, не потеряв возможности запихивать её в старые функции.
Вполне так решается агрегацией:
defecate-plusplus 19.03.2014 10:09 # +1
меня бесит, что по умолчанию в class всё private, неудобно же
bormand 19.03.2014 10:21 # +1
О да, "public:" писать же так дооолго... В жабе вон вообще почти к каждому полю или методу пишут, и ничего, живые.
> руки прочь от struct!
Да никто никогда его не тронет :) Совместимость же.
defecate-plusplus 19.03.2014 10:46 # 0
учитывая, что обычно класс/структура описывается в таком порядке, что сначала идут публичные поля, а в подвале - приватные
bormand 19.03.2014 11:18 # +1
Да ну, я и так всегда пишу class и public: для не POD'ов... Как-то не напрягает. Юзать struct чисто ради дефолтного паблика на верхнюю половину класса, имхо, как-то не айс...
Убрать дефолтный private/public вообще, чтобы положить конец битве остроконечников с тупоконечниками. Пусть пишут явно в обоих случаях.
absolut 19.03.2014 11:01 # 0
roman-kashitsyn 19.03.2014 10:26 # +1
Вам в D. Который, правда, всё равно не взлетит, т.к. самое важное в нём явно скоро доперетащат в кресты...
absolut 19.03.2014 11:03 # 0
Угу. Останется в недрах лицакниги при поддержке Александреску.
roman-kashitsyn 19.03.2014 11:09 # +2
bormand 19.03.2014 11:17 # 0
Судя по всему что-то совсем небольшое и простенькое. Или D настолько компактней c++, что в такой объем войдет что-то серьезное?
absolut 19.03.2014 11:26 # +2
roman-kashitsyn 19.03.2014 11:37 # 0
На первый взгляд он максимум в 1,5-2 раза компактней. Проверять, написав что-то нетривиальное на том и на другом желания никакого, как и вообще писать что-то на D.
Цитирую одного из разработчиков D1:
Now using Eclipse + C Dev Tools (CDT) and GCC as the IDE and tool-chain respectively, I feel I'm back to really cooking on gas once again.
"Oh C++, why did I ever leave you?"
absolut 19.03.2014 11:47 # 0
roman-kashitsyn 19.03.2014 11:52 # +1
Да это всё понятно. И на сайте d написано, что как и с чем можно линковать.
P.S. книжка александреску вышла в том же году :)
absolut 19.03.2014 11:20 # 0
absolut 19.03.2014 11:00 # +3
шарпопуть
TarasB 19.03.2014 12:53 # 0
зря, динамитор таки нужен
bormand 19.03.2014 13:17 # +1
Или я не так понял твою идею?
TarasB 19.03.2014 20:43 # 0
И после динамирования они становятся неподами.
bormand 19.03.2014 20:56 # 0
TarasB 19.03.2014 20:59 # 0
bormand 19.03.2014 07:50 # +1
И в 146% из них вообще не написаны деструкторы, т.к. дефолтная реализация вполне устраивает ;)
roman-kashitsyn 18.03.2014 15:56 # +5
Это полный бред. При конструировании компилятор точно знает, какой тип конструируется, и может правильно сгенерировать код инициализации. Деструктор же может вызваться непонятно где на объекте неизвестного компилятору класса (есть только указатель на базу), компилятор не может правильно уничтожить иерархию без поддержки рантайма.
Если не уничтожать объекты по указателям на базу (например, всегда аллоцировать их на стеке), механизмы конструирования и деконструкции корректны и симметричны.
TarasB 18.03.2014 15:56 # +3
Более того, в крестах конструктор не бывает виртуальным хихи
Pythoner 18.03.2014 16:15 # −4
1) Если не объявить деструктор виртуальным, вызовется деструктор только базового класса.
2) Есои обьявить его виртуальным, последовательновызовуться все леструкторы предков этого класса.
3) Конструктор работает так же, как виртуальный леструктор - вызываются все конструкторы предков.
Вопрос: нафига козе баян - нафиг описывать деструктор как virtual, если по другому и не над чтоб он работал?пс пишу с тела, сори за ошибки.
roman-kashitsyn 18.03.2014 16:22 # +2
Правда чтоли?
Pythoner 18.03.2014 16:31 # −3
roman-kashitsyn 18.03.2014 16:41 # +5
GCC 4.8.1, там как раз всё по стандарту. Аналогичный результат был бы на Borland C++ девяностых годов.
> вызывается только деструктор Base
Может всё же попробовать понять разницу между разрушением объекта известного типа и удалением указателя на базовый класс?
defecate-plusplus 18.03.2014 16:47 # +2
завидую твоему свободному времени
roman-kashitsyn 18.03.2014 16:51 # +2
absolut 18.03.2014 17:29 # +2
bormand 18.03.2014 22:36 # 0
P.S. Да и Тарас с Романом вполне справляются ;)
Abbath 18.03.2014 22:57 # 0
bormand 18.03.2014 23:22 # 0
Я в том районе совсем недолго был - поднялся со стороны озера с гидрой, увидел что-то похожее на ходячий гриб, хотел разглядеть поближе, и тут из-за деревьев выбежал большой кошак...
Так что с грибами пообщаться пока не довелось.
Abbath 18.03.2014 23:26 # +1
https://www.youtube.com/watch?v=jWkPpTv1vXk
bormand 19.03.2014 18:47 # 0
P.S. Волка жалко ;(
TarasB 18.03.2014 17:36 # +1
absolut 18.03.2014 17:34 # +2
http://ideone.com/zGxwzm
defecate-plusplus 18.03.2014 18:50 # +2
http://ideone.com/7SRoRr
absolut 18.03.2014 17:36 # +3
за логические?
eth0 18.03.2014 20:51 # +2