Нашли или выдавили из себя код, который нельзя назвать нормальным,
на который без улыбки не взглянешь?
Не торопитесь его удалять или рефакторить, — запостите его на
говнокод.ру, посмеёмся вместе!
#include <iostream>
using namespace std;
struct T{int a;T(){cout<<"T"<<this<<endl;}~T(){cout<<"~T"<<this<<endl;}};
struct D:public T{int b;D(){cout<<"D"<<this<<endl;}~D(){cout<<"~D"<<this<<endl;}};
int main() {
T* a = new D[2];
cout<<"mission failure"<<endl;
delete[] a;
return 0;
}
Писал тест специально для Тараса:
Виртуальный деструктор в базовых классах нужен:
*Для вызова деструкторов всех потомков. Иногда это не нужно, тк поля структуры тривиальны. Согласен с Тарасом.
*Для правильного выбора перегруженного оператора delete. Создал одним менеджером памяти, а удалил в другой - это плохо. Но также бывает редко и только в специфичных проектах.
Но вот то, что демонстрируется в этом примере - думаю чего-нибудь такого создатели той библиотеки, что ковырял Тарас, и опасались.
Не просто было вызван деструктор только для предков, забыв о деструкторах потомков, но и:
*Деструктор предков был вызван для this не по тем адресам, где расположены объекты.
Не удивлюсь, если:
*В некоторых кулхацкерских реализациях менеджеров памяти будет удален буфер меньшего размера и куча попортится или оставшаяся не удаленная часть массива в куче просто утекет. http://liveworkspace.org/code/2X3MR0$8
Я знал, что крестоблуды заминусуют, и это лишнее подтверждение.
Если хочется извращений для души, пожалуйста, миллион способов их получить. Напишите объектро-ориентированный Malbolge и занимайтесь содомией до смерти. Но если хочется достигнуть цели, они не нужны.
Сам слез с крестов 3 года назад, ни о чем не жалею.
См. ниже.
Быдлосишарпик - хороший язык для своих задач.
Его создатели собрались и сказали, давайте возьмем С++ и выкинем из него все детские грабли. Пусть он будет медленным и домохозяечным, зато программисты не отобьют себе яйца с первого же шага.
Я вижу баттхёрт уборщикоблядей. Я знаю, что уборщик может быть с гарантированной верхней границй задержки, но ведь хуй кто такими пользуется, почему - не знаю. Да и нахрен они не нужны.
По воле долга (временно) перелез с жабы на плюсы, не сказать, что получаю баттхёрт или наступаю на грабли. Не знаю вот теперь, как буду возвращаться на жабу, где нет деструкторов, шаблонов и boost.
> Метопрагромирванье забыл упомянуть
Я его не особо использую, ибо
1) я пишу код, который будут читать другие люди, скорее всего, не особо искушённые в мета-
2) нет пока особой потребности, а метапрограммирование ради метапрограммирования мне неинтересно
Как же так? Это свитая обязанность каждого крестушка нагенерировать кода через шаблоны, чтобы проект компилировался подольше, а тем временем: http://xkcd.ru/i/303_v1.png
Забавно, но если раскомментировать строку, то http://liveworkspace.org/code/lGIIZ$21
, то не скомпилируется, хотя "лишний" конструктор от int максимально спрятан и вроде влиять не должен.
#include <iostream>
using namespace std;
struct D
{
template<class T>
operator T() const {return T();}
};
struct M
{
M(){cout<<"M";}
M(const M&){cout<<"koko";}
//private: explicit M(int){cout<<"ops";}
};
int main() {
M a((D()));
cout<<"ko";
return 0;
}
с++ 98, 12.3 Conversions, пункт 2: User-defined conversions are applied only where they are unambiguous (10.2, 12.3.2). Conversions obey the access control rules (clause 11). Access control is applied after ambiguity resolution (3.4).
> вот теперь, как буду возвращаться на жабу, где нет деструкторов, шаблонов и boost.
Но зачем?
> не сказать, что получаю баттхёрт или наступаю на грабли
Ну и на кой она нужна? По сути сей язык изобрели-то для тех кто обезьян, которые не осилили (и не смогут осилить) плюсы.
В плюсиках и перегрузка операторов, и лямбды.
А в жабе что? Мегабайты xmlя и паттерны?
Ведь удобней бриться острой бритвой, чем тупой жабой. Просто надо быть осмотрительным.
Шарпик - кресты 00-х. Туда пихают всё подряд, без меры.
Жаба просто не стала быдловской из-за неудобной либы и выского порога вхождения.
Для крестов был быдлер, для пхп денвер, для шарпа - студия.
Сначала по работе C#.
Потом Common Lisp, Objective-C
Сейчас вот опять приходится к С++ возращаться, точнее к особо извращенной гибродной его форме Objective-C++, потому что некоторые библиотеки чисто на С++, их надо как-то присовокуплять к остальному коду.
Я не утвраждаю, что C++ говно, просто меня расстраивает неистовое стремление некоторых превратить его богатый набор возможностей в говенное кровавое месиво. И эта тенденция последнее время стала повальной.
Ага, нормально, только если в прошлом случае прогу не распидорашивало к хуям, из-за того что вызывался не тот деструктор, то теперь будет. (Что, впрочем, лучше, т.к. молчаливая ошибка хуже краша).
Она не удалится. delete[] посчитает это массивом более мелких элементов (T), и начнет вызывать у них по порядку деструкторы. На некоторых ему повезет, и там действительно окажется vtable от D, и вызовется деструктор от D, на некоторых вместо vtable будет хуита данные из середины других D. Собственно дойдя до кривого vtable delete[] попытается найти в нем виртуальный деструктор и ... кровь-кишки-распидорасило.
P.S. Забавно, но в gcc delete[] вызывает деструкторы от конца массива к началу, видимо так цикл получается оптимальней, а в стандарте все равно написано, что вызовутся все, но порядок не указан. Из-за этой фишки на данном примере не получится увидеть "правильно" вызванный деструктор.
Говно ты написал очередное. Обманул бедный компилятор крестов. Кастовать указатель на массив в указатель на массив других классов нельзя. Ни при каких обстоятельствах. Кастовать можно только указатель на один объект в указатель на другой объект, то что компилятор позволяет сделать то что ты написал - так он просто не понимает, чего ты там в этих указателях держишь - массив или один объект.
Если хочется извращений для души, пожалуйста, миллион способов их получить. Напишите объектро-ориентированный Malbolge и занимайтесь содомией до смерти. Но если хочется достигнуть цели, они не нужны.
Сам слез с крестов 3 года назад, ни о чем не жалею.
Быдлосишарпик - хороший язык для своих задач.
Его создатели собрались и сказали, давайте возьмем С++ и выкинем из него все детские грабли. Пусть он будет медленным и домохозяечным, зато программисты не отобьют себе яйца с первого же шага.
проверочное слово борьщ
ps: Метопрагромирванье забыл упомянуть.
Я его не особо использую, ибо
1) я пишу код, который будут читать другие люди, скорее всего, не особо искушённые в мета-
2) нет пока особой потребности, а метапрограммирование ради метапрограммирования мне неинтересно
http://xkcd.ru/i/303_v1.png
Ну или хотя бы на русском назовите.
http://liveworkspace.org/code/lGIIZ$21
, то не скомпилируется, хотя "лишний" конструктор от int максимально спрятан и вроде влиять не должен.
User-defined conversions are applied only where they are unambiguous (10.2, 12.3.2). Conversions obey the access control rules (clause 11). Access control is applied after ambiguity resolution (3.4).
P.S. А иксплисит тут вообще не в тему, ты же явно юзаешь конструктор.
Но зачем?
> не сказать, что получаю баттхёрт или наступаю на грабли
Ну и на кой она нужна? По сути сей язык изобрели-то для тех кто обезьян, которые не осилили (и не смогут осилить) плюсы.
В плюсиках и перегрузка операторов, и лямбды.
А в жабе что? Мегабайты xmlя и паттерны?
Ведь удобней бриться острой бритвой, чем тупой жабой. Просто надо быть осмотрительным.
Жаба просто не стала быдловской из-за неудобной либы и выского порога вхождения.
Для крестов был быдлер, для пхп денвер, для шарпа - студия.
Потом Common Lisp, Objective-C
Сейчас вот опять приходится к С++ возращаться, точнее к особо извращенной гибродной его форме Objective-C++, потому что некоторые библиотеки чисто на С++, их надо как-то присовокуплять к остальному коду.
Я не утвраждаю, что C++ говно, просто меня расстраивает неистовое стремление некоторых превратить его богатый набор возможностей в говенное кровавое месиво. И эта тенденция последнее время стала повальной.
Что это?
Че-нить типа
Или:
И прочий маразм 🙂
Ага, а T и D разного размера, оно хоть иногда нормально работает, a[1] корректно определяется?
http://liveworkspace.org/code/code/2X3MR0$9
виртуальный деструктор добавить, то нормально удаляется.
P.S. Забавно, но в gcc delete[] вызывает деструкторы от конца массива к началу, видимо так цикл получается оптимальней, а в стандарте все равно написано, что вызовутся все, но порядок не указан. Из-за этой фишки на данном примере не получится увидеть "правильно" вызванный деструктор.