А когда может не вызываться деструктор?
От: Аноним  
Дата: 23.01.13 17:48
Оценка:
Помогите новичку!
Какие могут быть ситуации, когда не вызывается дестуктор(сделал new и не сделал delete не в счет)?
Re: А когда может не вызываться деструктор?
От: Piko  
Дата: 23.01.13 17:52
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Помогите новичку!

А>Какие могут быть ситуации, когда не вызывается дестуктор(сделал new и не сделал delete не в счет)?

когда конструктор не отработал до конца т.е. вылетело исключение — деструкторы вызываются только для полностью созданных объектов.
Re: А когда может не вызываться деструктор?
От: rg45 СССР  
Дата: 23.01.13 18:07
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Помогите новичку!

А>Какие могут быть ситуации, когда не вызывается дестуктор(сделал new и не сделал delete не в счет)?

1. Когда бросается исключение, которое нигде не ловится.

2. (MSVC specific) при возникновении SEH исключений в приложении, в котором один из модулей (бросающий или перехватывающий это исключение) скомпилирован с выключенной опцией /EHa
--
Справедливость выше закона. А человечность выше справедливости.
Re[2]: А когда может не вызываться деструктор?
От: Nikita.Trophimov  
Дата: 23.01.13 18:49
Оценка: +1
R>1. Когда бросается исключение, которое нигде не ловится.

Это unspecified.
Re: А когда может не вызываться деструктор?
От: Nikita.Trophimov  
Дата: 23.01.13 18:50
Оценка:
Например, в случае использования longjmp.
Re: А когда может не вызываться деструктор?
От: Кодт Россия  
Дата: 23.01.13 19:17
Оценка: 19 (2) +1
Здравствуйте, Аноним, Вы писали:

А>Помогите новичку!

А>Какие могут быть ситуации, когда не вызывается дестуктор(сделал new и не сделал delete не в счет)?

А в связи с чем вопрос?
Ну, там
— на собеседовании спросили
— обнаружен баг
— обнаружено странное поведение
— нужно добиться такого поведения
и т.д.

А то можно всякого навыдумывать.
Любое завершение потока или процесса, не сопровождающееся раскруткой стека. То есть, terminate(), abort(), exit(), ExitThread(), TerminateThread(), SEH, signal...
Любой прыжок в коде. longjmp(), повреждение стека, указателя на функцию, указателя на таблицу виртуальных функций, с последующим переходом в чёрт знает куда.
Потеря информации о типе. delete (NonvirtualBase*) new Derived(), повреждение указателя на таблицу виртуальных функций (например, вместо присваивания сделали memcpy базового класса — подменили vfptr наследника на базовый).
Нарушение защиты памяти, повреждение секций кода или констант (таблицы виртуальных функций).
И прочая, и прочая, и прочая.
Перекуём баги на фичи!
Re[3]: А когда может не вызываться деструктор?
От: rg45 СССР  
Дата: 23.01.13 19:31
Оценка:
Здравствуйте, Nikita.Trophimov, Вы писали:

R>>1. Когда бросается исключение, которое нигде не ловится.


NT>Это unspecified.


Вопрос был, "когда может...". А в этом случае может.
--
Справедливость выше закона. А человечность выше справедливости.
Re: А когда может не вызываться деструктор?
От: vitcpp Россия http://vdavydov.ru
Дата: 23.01.13 21:30
Оценка: 1 (1) +1 -1
А>Какие могут быть ситуации, когда не вызывается дестуктор(сделал new и не сделал delete не в счет)?

Классический пример — отсутствие виртуального деструктора — http://cpp-reference.ru/articles/virtual-destructor/
Re[2]: А когда может не вызываться деструктор?
От: sts  
Дата: 25.01.13 12:37
Оценка:
Здравствуйте, vitcpp, Вы писали:

А>>Какие могут быть ситуации, когда не вызывается дестуктор(сделал new и не сделал delete не в счет)?


V>Классический пример — отсутствие виртуального деструктора — http://cpp-reference.ru/articles/virtual-destructor/


Это UB
Re[2]: А когда может не вызываться деструктор?
От: Abyx Россия  
Дата: 25.01.13 13:13
Оценка: -3 :)
Здравствуйте, vitcpp, Вы писали:

V>Классический пример — отсутствие виртуального деструктора — http://cpp-reference.ru/articles/virtual-destructor/


В языке программирования C++ деструктор полиморфного базового класса должен объявляться виртуальным.
Только так обеспечивается корректное разрушение объекта производного класса через указатель на соответствующий базовый класс.


это же чушь.
где Вы нашли этот говносайт?
In Zen We Trust
Re[4]: А когда может не вызываться деструктор?
От: Abyx Россия  
Дата: 25.01.13 13:14
Оценка: -4
Здравствуйте, rg45, Вы писали:

R>Здравствуйте, Nikita.Trophimov, Вы писали:


R>>>1. Когда бросается исключение, которое нигде не ловится.


NT>>Это unspecified.


R>Вопрос был, "когда может...". А в этом случае может.


в нормальных компиляторах не может.
In Zen We Trust
Re[3]: А когда может не вызываться деструктор?
От: sts  
Дата: 25.01.13 13:18
Оценка:
Здравствуйте, Abyx, Вы писали:

A>Здравствуйте, vitcpp, Вы писали:


V>>Классический пример — отсутствие виртуального деструктора — http://cpp-reference.ru/articles/virtual-destructor/


A>

A>В языке программирования C++ деструктор полиморфного базового класса должен объявляться виртуальным.
A>Только так обеспечивается корректное разрушение объекта производного класса через указатель на соответствующий базовый класс.


A>это же чушь.

A>где Вы нашли этот говносайт?

А что тут не так ?
Вроде как удаление через указатель на базовый с невиртуальным деструктором = UB (по стандарту 2003, а как по новому интересно ?)
Re[5]: А когда может не вызываться деструктор?
От: rg45 СССР  
Дата: 25.01.13 13:32
Оценка:
Здравствуйте, Abyx, Вы писали:

R>>>>1. Когда бросается исключение, которое нигде не ловится.


NT>>>Это unspecified.


R>>Вопрос был, "когда может...". А в этом случае может.


A>в нормальных компиляторах не может.


К сожалению, ТС ничего не сообщил о степени нормальности своего компилятора. Кроме того, раз стандарт допускает такое поведение, значит оно может иметь место в любых компиляторах.
--
Справедливость выше закона. А человечность выше справедливости.
Re[4]: А когда может не вызываться деструктор?
От: Abyx Россия  
Дата: 25.01.13 13:39
Оценка: -1
Здравствуйте, sts, Вы писали:

V>>>Классический пример — отсутствие виртуального деструктора — http://cpp-reference.ru/articles/virtual-destructor/


A>>

A>>В языке программирования C++ деструктор полиморфного базового класса должен объявляться виртуальным.
A>>Только так обеспечивается корректное разрушение объекта производного класса через указатель на соответствующий базовый класс.


A>>это же чушь.

A>>где Вы нашли этот говносайт?

sts>А что тут не так ?

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

sts>Вроде как удаление через указатель на базовый с невиртуальным деструктором = UB (по стандарту 2003, а как по новому интересно ?)

вызов delete — UB, но это же не единственный способ разрушить объект
In Zen We Trust
Re[3]: А когда может не вызываться деструктор?
От: vitcpp Россия http://vdavydov.ru
Дата: 25.01.13 13:40
Оценка:
A>

A>В языке программирования C++ деструктор полиморфного базового класса должен объявляться виртуальным.
A>Только так обеспечивается корректное разрушение объекта производного класса через указатель на соответствующий базовый класс.


A>это же чушь.

A>где Вы нашли этот говносайт?
Почему чушь? Обоснуйте.
Re[3]: А когда может не вызываться деструктор?
От: rg45 СССР  
Дата: 25.01.13 13:42
Оценка:
Здравствуйте, Abyx, Вы писали:

A>Здравствуйте, vitcpp, Вы писали:


V>>Классический пример — отсутствие виртуального деструктора — http://cpp-reference.ru/articles/virtual-destructor/


A>

A>В языке программирования C++ деструктор полиморфного базового класса должен объявляться виртуальным.
A>Только так обеспечивается корректное разрушение объекта производного класса через указатель на соответствующий базовый класс.


A>это же чушь.


Это высказывание является прямым следствием из 5.3.5/3.

A>где Вы нашли этот говносайт?


А с сайтом что не так?
--
Справедливость выше закона. А человечность выше справедливости.
Re[3]: А когда может не вызываться деструктор?
От: vitcpp Россия http://vdavydov.ru
Дата: 25.01.13 13:42
Оценка: :)
V>>Классический пример — отсутствие виртуального деструктора — http://cpp-reference.ru/articles/virtual-destructor/
sts>Это UB

UB или не UB, но вопросом по поводу виртуального деструктора отсекали соискателей еще по телефонному собеседованию лет 5 еще назад.
Re[4]: А когда может не вызываться деструктор?
От: Abyx Россия  
Дата: 25.01.13 13:47
Оценка: -1
Здравствуйте, vitcpp, Вы писали:

V>Почему чушь? Обоснуйте.


http://rsdn.ru/forum/cpp/5044673.1
Автор: Abyx
Дата: 25.01.13
In Zen We Trust
Re[4]: А когда может не вызываться деструктор?
От: Abyx Россия  
Дата: 25.01.13 13:52
Оценка: +1
Здравствуйте, rg45, Вы писали:

A>>

A>>В языке программирования C++ деструктор полиморфного базового класса должен объявляться виртуальным.
A>>Только так обеспечивается корректное разрушение объекта производного класса через указатель на соответствующий базовый класс.


A>>это же чушь.


R>Это высказывание является прямым следствием из 5.3.5/3.

это не может быть следствием, т.к. `delete pointer-to-base-type;` это не единственный способ корректно разрушить объект через указатель на его базовый класс.

R>А с сайтом что не так?

то что на нем такие статьи
In Zen We Trust
Re[5]: А когда может не вызываться деструктор?
От: vitcpp Россия http://vdavydov.ru
Дата: 25.01.13 13:57
Оценка:
V>>Почему чушь? Обоснуйте.
A>http://rsdn.ru/forum/cpp/5044673.1
Автор: Abyx
Дата: 25.01.13


Это все понятно. Полагаю, вы слишком формально подходите к статье, и вас смутило слово "должен". Но по сути, описано хорошее правило делать деструктор виртуальным в случае полиморфных типов. Можно использовать обычный деструктор, если вы точно уверены, как именно ваша иерархия классов будет использоваться или в целях оптимизации.
Re[4]: А когда может не вызываться деструктор?
От: jazzer Россия Skype: enerjazzer
Дата: 25.01.13 14:03
Оценка: +1
Здравствуйте, rg45, Вы писали:

A>>

A>>В языке программирования C++ деструктор полиморфного базового класса должен объявляться виртуальным.
A>>Только так обеспечивается корректное разрушение объекта производного класса через указатель на соответствующий базовый класс.


A>>это же чушь.


R>Это высказывание является прямым следствием из 5.3.5/3.


struct A { virtual f(); ~A(); };
struct B:A { f(); };

int main()
{
  B b;
  A* pa = &b;
  pa->f(); //полиморфный!
}

Здесь В замечательно обходится без виртуального деструктора и все корректно уничтожается, а 5.3.5/3 идет по градиенту.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[2]: А когда может не вызываться деструктор?
От: Evgeny.Panasyuk Россия  
Дата: 25.01.13 14:10
Оценка: +1
А>>Какие могут быть ситуации, когда не вызывается дестуктор(сделал new и не сделал delete не в счет)?

V>Классический пример — отсутствие виртуального деструктора — http://cpp-reference.ru/articles/virtual-destructor/


В языке программирования C++ деструктор полиморфного базового класса должен объявляться виртуальным.
Только так обеспечивается корректное разрушение объекта производного класса через указатель на соответствующий базовый класс.

Технически никому он ничего не должен, особенно если:
1. он protected
2. delete вызывается не на Base*, хотя хранится именно Base* (например deleter в shared_ptr знающий правильный тип, хотя хранится Base*)
3. как показано выше — объект может быть локальным

Но, ссылка выше это же rule of thumb для новичков?
Re[5]: А когда может не вызываться деструктор?
От: sts  
Дата: 25.01.13 14:13
Оценка:
Здравствуйте, jazzer, Вы писали:

J>int main()

J>{
J> B b;
J> A* pa = &b;
pa->>f(); //полиморфный!
J>}
J>[/ccode]
J>Здесь В замечательно обходится без виртуального деструктора и все корректно уничтожается, а 5.3.5/3 идет по градиенту.

разрушение объекта производного класса через указатель на соответствующий базовый класс

тут нет уничтожения через указатель на базовый
Re[3]: А когда может не вызываться деструктор?
От: sts  
Дата: 25.01.13 14:19
Оценка: +1 -1
Здравствуйте, Evgeny.Panasyuk, Вы писали:

А>>>Какие могут быть ситуации, когда не вызывается дестуктор(сделал new и не сделал delete не в счет)?


V>>Классический пример — отсутствие виртуального деструктора — http://cpp-reference.ru/articles/virtual-destructor/


EP>

EP>В языке программирования C++ деструктор полиморфного базового класса должен объявляться виртуальным.
EP>Только так обеспечивается корректное разрушение объекта производного класса через указатель на соответствующий базовый класс.

EP>Технически никому он ничего не должен, особенно если:
EP>1. он protected
тогда не получится "удалять через указатель на базовый класс"
EP>2. delete вызывается не на Base*, хотя хранится именно Base* (например deleter в shared_ptr знающий правильный тип, хотя хранится Base*)
там нет "удаления через указатель на базовый класс" — сначала указателю делается статик-каст к фактическому типу
EP>3. как показано выше — объект может быть локальным
там тоже нет "удаления через указатель на базовый класс"

EP>Но, ссылка выше это же rule of thumb для новичков?

это да
но и пятница же
Re[4]: А когда может не вызываться деструктор?
От: Evgeny.Panasyuk Россия  
Дата: 25.01.13 14:26
Оценка: +2 :))
Здравствуйте, sts, Вы писали:

sts>тогда не получится "удалять через указатель на базовый класс"


sts>там нет "удаления через указатель на базовый класс" — сначала указателю делается статик-каст к фактическому типу


sts>там тоже нет "удаления через указатель на базовый класс"


это же ответ на:

В языке программирования C++ деструктор полиморфного базового класса должен объявляться виртуальным.

которое стоит самым первым предложением.

По аналогии можно сказать:

На планете Земля, все люди должны носить шлем. Только так обеспечивается защита головы при падениях с мотоцикла.



EP>>Но, ссылка выше это же rule of thumb для новичков?

sts>это да
sts>но и пятница же

Re: А когда может не вызываться деструктор?
От: sts  
Дата: 25.01.13 14:27
Оценка: -1
Здравствуйте, Аноним, Вы писали:

А>Помогите новичку!

А>Какие могут быть ситуации, когда не вызывается дестуктор(сделал new и не сделал delete не в счет)?

Ну еще на такое можно нарваться:
// .h

struct Owner
{
  Owner();
  // ~Owner();
  std::auto_ptr<class Impl> pImpl;
};


// .cpp

#include "Impl.h"

Owner::Owner()
  : pImpl(new Impl())
{}

//Owner::~Owner()
//{}


Удаление неполного класса — одни из самых неприятных плюсовых граблей.
Тоже деструктор pImpl не будет вызван.
Лечится через unique_ptr (который не даст удалить неполный тип) и добавление ~Owner() туда, где Impl уже определен.
Re[5]: А когда может не вызываться деструктор?
От: sts  
Дата: 25.01.13 14:32
Оценка: -1
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>

EP>В языке программирования C++ деструктор полиморфного базового класса должен объявляться виртуальным.

EP>которое стоит самым первым предложением.

EP>По аналогии можно сказать:

EP>

EP>На планете Земля, все люди должны носить шлем. Только так обеспечивается защита головы при падениях с мотоцикла.


я понял кто за что борется
ну да, не должен
но корректное удаление через указатель на объект базового класса только так
Re[5]: А когда может не вызываться деструктор?
От: rg45 СССР  
Дата: 25.01.13 14:42
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Здравствуйте, rg45, Вы писали:


A>>>

A>>>В языке программирования C++ деструктор полиморфного базового класса должен объявляться виртуальным.
A>>>Только так обеспечивается корректное разрушение объекта производного класса через указатель на соответствующий базовый класс.


A>>>это же чушь.


R>>Это высказывание является прямым следствием из 5.3.5/3.


J>
J>struct A { virtual f(); ~A(); };
J>struct B:A { f(); };

J>int main()
J>{
J>  B b;
J>  A* pa = &b;
  pa->>f(); //полиморфный!
J>}
J>

J>Здесь В замечательно обходится без виртуального деструктора и все корректно уничтожается, а 5.3.5/3 идет по градиенту.

Где в этом примере (цитирую) "разрушение объекта производного класса через указатель на соответствующий базовый класс" о котором шла речь выше?

Да, к сожалению, авторы статьи не дали четкого определения, что они понимают под полиморфным классом. Из общего контекста статьи можно догадаться, что они вкладывали в это понятие более широкий смысл — класс, объекты которого могут не только использоваться, но и удаляться через указатель базового класса (именно этому вопросу в статье уделено много внимания). Конечно же, это недочет, неточность формулировки, но еще не повод разбрасываться ярлыками типа "чушь" и "говносайт".
--
Справедливость выше закона. А человечность выше справедливости.
Re[6]: А когда может не вызываться деструктор?
От: Abyx Россия  
Дата: 25.01.13 15:09
Оценка:
Здравствуйте, vitcpp, Вы писали:

V>>>Почему чушь? Обоснуйте.

A>>http://rsdn.ru/forum/cpp/5044673.1
Автор: Abyx
Дата: 25.01.13


V>Это все понятно. Полагаю, вы слишком формально подходите к статье, и вас смутило слово 'должен'. Но по сути, описано хорошее правило делать деструктор виртуальным в случае полиморфных типов. Можно использовать обычный деструктор, если вы точно уверены, как именно ваша иерархия классов будет использоваться или в целях оптимизации.


хорошее правило — это 'не делать того что не нужно делать' или 'делать только то что нужно делать'.
если виртуальный деструктор не нужен, то незачем его делать.
In Zen We Trust
Re[5]: А когда может не вызываться деструктор?
От: rg45 СССР  
Дата: 25.01.13 15:10
Оценка: +1
Здравствуйте, Abyx, Вы писали:

A>это не может быть следствием, т.к. `delete pointer-to-base-type;` это не единственный способ корректно разрушить объект через указатель на его базовый класс.


Вероятно, ты имеешь ввиду технику, подобную той, которая применяется в shared_ptr? Ну так в ней разрушение объекта производится как раз через указатель most derived класса (при правильно использовании, при неправильном можно получить все то же UB). При этом сам shared_ptr я бы рассматривал не как способ разрушения объекта, а как средство абстрагирования от деталей этого процесса.

Или ты что-то другое имеешь в виду? Ну тогда поделись, как еще можно разрушить объект через указатель на его базовый класс.
--
Справедливость выше закона. А человечность выше справедливости.
Re[6]: А когда может не вызываться деструктор?
От: Abyx Россия  
Дата: 25.01.13 15:28
Оценка: -1
Здравствуйте, rg45, Вы писали:

A>>это не может быть следствием, т.к. `delete pointer-to-base-type;` это не единственный способ корректно разрушить объект через указатель на его базовый класс.


R>Вероятно, ты имеешь ввиду технику, подобную той, которая применяется в shared_ptr? Ну так в ней разрушение объекта производится как раз через указатель most derived класса (при правильно использовании, при неправильном можно получить все то же UB). При этом сам shared_ptr я бы рассматривал не как способ разрушения объекта, а как средство абстрагирования от деталей этого процесса.


R>Или ты что-то другое имеешь в виду? Ну тогда поделись, как еще можно разрушить объект через указатель на его базовый класс.


да, удалять объект можно с помощью deleter'а с type-erasure как у shared_ptr,
причем *внезапно* shared_ptr<BaseClass> это *указатель* на базовый класс.

еще объект может владеть сам собой (встроенный счетчик ссылок и delete this, как например в COM),
объект может удалять какой-то GC (напр. Arena GC), впрочем это опять же deleter.

много в общем разных способов.
In Zen We Trust
Re[6]: А когда может не вызываться деструктор?
От: Abyx Россия  
Дата: 25.01.13 15:37
Оценка: -1
Здравствуйте, rg45, Вы писали:

A>>>>

A>>>>В языке программирования C++ деструктор полиморфного базового класса должен объявляться виртуальным.
A>>>>Только так обеспечивается корректное разрушение объекта производного класса через указатель на соответствующий базовый класс.


R>Да, к сожалению, авторы статьи не дали четкого определения, что они понимают под полиморфным классом. Из общего контекста статьи можно догадаться, что они вкладывали в это понятие более широкий смысл — класс, объекты которого могут не только использоваться, но и удаляться через указатель базового класса (именно этому вопросу в статье уделено много внимания). Конечно же, это недочет, неточность формулировки, но еще не повод разбрасываться ярлыками типа "чушь" и "говносайт".


вот поэтому статья и говно, раз там написана чушь наподобие "раз полиморфный — значит ДОЛЖЕН быть виртуальный деструктор".
про весь сайт я может погорячился, хотя раз там есть статья такого качества — наверное и весь сайт такой.

у термина "полиморфный (класс)" есть вполне конкретное определение.
то что на это определение наложено ограничение, что объекты потомков такого класса будут удаляться через delete — это называется "более узкий смысл".
In Zen We Trust
Re[4]: А когда может не вызываться деструктор?
От: Abyx Россия  
Дата: 25.01.13 15:41
Оценка: -1
Здравствуйте, sts, Вы писали:

EP>>

EP>>В языке программирования C++ деструктор полиморфного базового класса должен объявляться виртуальным.
EP>>Только так обеспечивается корректное разрушение объекта производного класса через указатель на соответствующий базовый класс.

EP>>Технически никому он ничего не должен, особенно если:
EP>>1. он protected
sts>тогда не получится "удалять через указатель на базовый класс"

не подменяйте тему.
в цитате написано не "удалять", а разрушать.
это разные вещи.
In Zen We Trust
Re[2]: А когда может не вызываться деструктор?
От: Abyx Россия  
Дата: 25.01.13 15:42
Оценка: -1
Здравствуйте, sts, Вы писали:

sts>Удаление неполного класса — одни из самых неприятных плюсовых граблей.

sts>Тоже деструктор pImpl не будет вызван.
sts>Лечится через unique_ptr (который не даст удалить неполный тип) и добавление ~Owner() туда, где Impl уже определен.

лечится включением предупреждений в компиляторе.
In Zen We Trust
Re: Разрушение компа прежде, чем будет разрушен объект, покатит? ;)
От: Erop Россия  
Дата: 25.01.13 15:43
Оценка: +1 :)
Здравствуйте, Аноним, Вы писали:

А>Какие могут быть ситуации, когда не вызывается дестуктор(сделал new и не сделал delete не в счет)?


на пример, если объёкт создали на компе, установленном на борут ГЧ, достигшей цели
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[7]: А когда может не вызываться деструктор?
От: rg45 СССР  
Дата: 25.01.13 16:16
Оценка: +1
Здравствуйте, Abyx, Вы писали:

A>>>это не может быть следствием, т.к. `delete pointer-to-base-type;` это не единственный способ корректно разрушить объект через указатель на его базовый класс.


R>>Вероятно, ты имеешь ввиду технику, подобную той, которая применяется в shared_ptr? Ну так в ней разрушение объекта производится как раз через указатель most derived класса (при правильно использовании, при неправильном можно получить все то же UB). При этом сам shared_ptr я бы рассматривал не как способ разрушения объекта, а как средство абстрагирования от деталей этого процесса.


R>>Или ты что-то другое имеешь в виду? Ну тогда поделись, как еще можно разрушить объект через указатель на его базовый класс.


A>да, удалять объект можно с помощью deleter'а с type-erasure как у shared_ptr,

A>причем *внезапно* shared_ptr<BaseClass> это *указатель* на базовый класс.

A>еще объект может владеть сам собой (встроенный счетчик ссылок и delete this, как например в COM),

A>объект может удалять какой-то GC (напр. Arena GC), впрочем это опять же deleter.

A>много в общем разных способов.


Я понимаю, о чем ты говоришь, более того, сам придерживаюсь примерно тех же взглядов, и уже писал ранее по данной теме: http://rsdn.ru/forum/cpp/4071405.1
Автор: rg45
Дата: 09.12.10
. Как мне кажется, при изучении C++ вообще, и особенно таких вопросов как времени жизни объектов и владение, прежде чем приступать к вопросам дизайна и паттернам проектирования, нужно познакомиться с синтаксисом и базовыми концепциями C++ на несколько более низком уровне. Название сайта "C++ reference" несколько ввело меня в заблуждение — я подумал, что его авторы как раз и поставили перед собой задачу познакомить читателя с основами языка, поэтому и не удивился, что они достаточно узко рассматривают вопросы удаления объектов, не рассматривая других аспектов и возможных реализаций владения. Хотя, могли бы, с учетом того, что паттернам они таки уделяют некоторое внимание.
--
Справедливость выше закона. А человечность выше справедливости.
Re[6]: А когда может не вызываться деструктор?
От: jazzer Россия Skype: enerjazzer
Дата: 25.01.13 16:22
Оценка: +1
Здравствуйте, rg45, Вы писали:

R>Здравствуйте, jazzer, Вы писали:


J>>Здравствуйте, rg45, Вы писали:


A>>>>

A>>>>В языке программирования C++ деструктор полиморфного базового класса должен объявляться виртуальным.
A>>>>Только так обеспечивается корректное разрушение объекта производного класса через указатель на соответствующий базовый класс.


A>>>>это же чушь.


R>>>Это высказывание является прямым следствием из 5.3.5/3.


J>>
J>>struct A { virtual f(); ~A(); };
J>>struct B:A { f(); };

J>>int main()
J>>{
J>>  B b;
J>>  A* pa = &b;
  pa->>>f(); //полиморфный!
J>>}
J>>

J>>Здесь В замечательно обходится без виртуального деструктора и все корректно уничтожается, а 5.3.5/3 идет по градиенту.

R>Где в этом примере (цитирую) "разрушение объекта производного класса через указатель на соответствующий базовый класс" о котором шла речь выше?


Нету, в том-то и дело. Полиморфное использование есть, а полиморфного удаления нету.

R>Да, к сожалению, авторы статьи не дали четкого определения, что они понимают под полиморфным классом. Из общего контекста статьи можно догадаться, что они вкладывали в это понятие более широкий смысл — класс, объекты которого могут не только использоваться, но и удаляться через указатель базового класса (именно этому вопросу в статье уделено много внимания). Конечно же, это недочет, неточность формулировки, но еще не повод разбрасываться ярлыками типа "чушь" и "говносайт".


Ну, я конкретно не разбрасывался, но заявления типа "В языке программирования C++ деструктор полиморфного базового класса должен объявляться виртуальным." и "Cуществует правило — если базовый класс предназначен для полиморфного использования, то его деструктор должен объявляться виртуальным." являются слишком смелым обобщением, годным разве что для совсем начинающих, чтоб не отстрелили себе что-нть.

Правильная формулировка была бы такой: "если базовый класс предназначен для полиморфного использования удаления, то его деструктор должен объявляться виртуальным. Т.е. если ты не собираешься удалять объекты по голому указателю на базовый класс — нет необходимости делать деструктор виртуальным.

Например, есть у тебя std::map< std::string, std::shared_ptr<А> > — так вот в такую мапу ты вполне можешь запихивать указатели на В, и все будет правильно удаляться безо всяких виртуальных деструкторов (есть такое свойство у shared_ptr — deleter внутри него инициализируется в самом начале, и поэтому он знает, какой класс надо удалять).
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[3]: А когда может не вызываться деструктор?
От: sts  
Дата: 25.01.13 16:43
Оценка: -1
Здравствуйте, Abyx, Вы писали:

A>Здравствуйте, sts, Вы писали:


sts>>Удаление неполного класса — одни из самых неприятных плюсовых граблей.

sts>>Тоже деструктор pImpl не будет вызван.
sts>>Лечится через unique_ptr (который не даст удалить неполный тип) и добавление ~Owner() туда, где Impl уже определен.

A>лечится включением предупреждений в компиляторе.


что лечится ?
если включить предупреждения, то деструктор вызовется ?
не верю
Re[2]: Разрушение компа прежде, чем будет разрушен объект, покатит? ;)
От: sts  
Дата: 25.01.13 16:51
Оценка:
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, Аноним, Вы писали:


А>>Какие могут быть ситуации, когда не вызывается дестуктор(сделал new и не сделал delete не в счет)?


E>на пример, если объёкт создали на компе, установленном на борут ГЧ, достигшей цели


так ведь и delete не успели сделатьт, так что это не в счет
Re[3]: Разрушение компа прежде, чем будет разрушен объект, покатит? ;)
От: Erop Россия  
Дата: 25.01.13 17:02
Оценка:
Здравствуйте, sts, Вы писали:

А>>>Какие могут быть ситуации, когда не вызывается дестуктор(сделал new и не сделал delete не в счет)?


E>>на пример, если объёкт создали на компе, установленном на борут ГЧ, достигшей цели


sts>так ведь и delete не успели сделатьт, так что это не в счет

Ты ТС или просто рассуждаешь?
Я так понял, что ТС спросил, когда может так получится, что у созхданного С++ объекта не будет вызван деструктор. при этом случай с забытым delete, он считал тривиальным и просил на него не отвлекаться. на этот вопрос я и ответил...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[4]: Разрушение компа прежде, чем будет разрушен объект, покатит? ;)
От: sts  
Дата: 25.01.13 17:20
Оценка:
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, sts, Вы писали:


А>>>>Какие могут быть ситуации, когда не вызывается дестуктор(сделал new и не сделал delete не в счет)?


E>>>на пример, если объёкт создали на компе, установленном на борут ГЧ, достигшей цели


sts>>так ведь и delete не успели сделатьт, так что это не в счет

E>Ты ТС или просто рассуждаешь?
E>Я так понял, что ТС спросил, когда может так получится, что у созхданного С++ объекта не будет вызван деструктор. при этом случай с забытым delete, он считал тривиальным и просил на него не отвлекаться. на этот вопрос я и ответил...

брутально, можно было никого не взрывать, а просто комп из розетки выдернуть
Re[5]: А когда может не вызываться деструктор?
От: sts  
Дата: 25.01.13 18:34
Оценка: -1
Здравствуйте, Abyx, Вы писали:

A>Здравствуйте, sts, Вы писали:


EP>>>

EP>>>В языке программирования C++ деструктор полиморфного базового класса должен объявляться виртуальным.
EP>>>Только так обеспечивается корректное разрушение объекта производного класса через указатель на соответствующий базовый класс.

EP>>>Технически никому он ничего не должен, особенно если:
EP>>>1. он protected
sts>>тогда не получится "удалять через указатель на базовый класс"

A>не подменяйте тему.

A>в цитате написано не "удалять", а разрушать.
A>это разные вещи.

это уже демагогия
Re[7]: А когда может не вызываться деструктор?
От: sts  
Дата: 25.01.13 18:36
Оценка:
Здравствуйте, Abyx, Вы писали:

A>Здравствуйте, vitcpp, Вы писали:


V>>>>Почему чушь? Обоснуйте.

A>>>http://rsdn.ru/forum/cpp/5044673.1
Автор: Abyx
Дата: 25.01.13


V>>Это все понятно. Полагаю, вы слишком формально подходите к статье, и вас смутило слово 'должен'. Но по сути, описано хорошее правило делать деструктор виртуальным в случае полиморфных типов. Можно использовать обычный деструктор, если вы точно уверены, как именно ваша иерархия классов будет использоваться или в целях оптимизации.


A>хорошее правило — это 'не делать того что не нужно делать' или 'делать только то что нужно делать'.

A>если виртуальный деструктор не нужен, то незачем его делать.

в данном случае это надо делать (делать деструктор виртуальным), т.к. большинство разработчиков этого ожидают
Re[7]: А когда может не вызываться деструктор?
От: sts  
Дата: 25.01.13 18:39
Оценка:
Здравствуйте, Abyx, Вы писали:

A>Здравствуйте, rg45, Вы писали:


A>>>это не может быть следствием, т.к. `delete pointer-to-base-type;` это не единственный способ корректно разрушить объект через указатель на его базовый класс.


R>>Вероятно, ты имеешь ввиду технику, подобную той, которая применяется в shared_ptr? Ну так в ней разрушение объекта производится как раз через указатель most derived класса (при правильно использовании, при неправильном можно получить все то же UB). При этом сам shared_ptr я бы рассматривал не как способ разрушения объекта, а как средство абстрагирования от деталей этого процесса.


R>>Или ты что-то другое имеешь в виду? Ну тогда поделись, как еще можно разрушить объект через указатель на его базовый класс.


A>да, удалять объект можно с помощью deleter'а с type-erasure как у shared_ptr,

A>причем *внезапно* shared_ptr<BaseClass> это *указатель* на базовый класс.

A>еще объект может владеть сам собой (встроенный счетчик ссылок и delete this, как например в COM),

A>объект может удалять какой-то GC (напр. Arena GC), впрочем это опять же deleter.

A>много в общем разных способов.


нету в shared_ptr удаления через указатель на базовый класс — там базовый класс кастуется к нужному прежде чем удалить
Re[7]: А когда может не вызываться деструктор?
От: sts  
Дата: 25.01.13 18:40
Оценка:
Здравствуйте, Abyx, Вы писали:

A>Здравствуйте, rg45, Вы писали:


A>>>>>

A>>>>>В языке программирования C++ деструктор полиморфного базового класса должен объявляться виртуальным.
A>>>>>Только так обеспечивается корректное разрушение объекта производного класса через указатель на соответствующий базовый класс.


R>>Да, к сожалению, авторы статьи не дали четкого определения, что они понимают под полиморфным классом. Из общего контекста статьи можно догадаться, что они вкладывали в это понятие более широкий смысл — класс, объекты которого могут не только использоваться, но и удаляться через указатель базового класса (именно этому вопросу в статье уделено много внимания). Конечно же, это недочет, неточность формулировки, но еще не повод разбрасываться ярлыками типа "чушь" и "говносайт".


A>вот поэтому статья и говно, раз там написана чушь наподобие "раз полиморфный — значит ДОЛЖЕН быть виртуальный деструктор".

A>про весь сайт я может погорячился, хотя раз там есть статья такого качества — наверное и весь сайт такой.

A>у термина "полиморфный (класс)" есть вполне конкретное определение.

A>то что на это определение наложено ограничение, что объекты потомков такого класса будут удаляться через delete — это называется "более узкий смысл".

ожидается, что деструктор будет полиморфным
так же как ожидается, что из него не будет выкинуто исключение
Re: А когда может не вызываться деструктор?
От: Фаллопиева труба  
Дата: 25.01.13 19:41
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Помогите новичку!

А>Какие могут быть ситуации, когда не вызывается дестуктор(сделал new и не сделал delete не в счет)?

Деструкторы могут не вызываться при создании массива с помощью оператора new[] и удалении его(массива) с помощью оператора delete.

Пример:

class A
{
public:
~A(){}
};

int main()
{
A* a = new A[100500];
...
delete a; // should be delete[] a;
}
array destructor
Re[8]: А когда может не вызываться деструктор?
От: Abyx Россия  
Дата: 25.01.13 20:13
Оценка:
Здравствуйте, sts, Вы писали:

V>>>Это все понятно. Полагаю, вы слишком формально подходите к статье, и вас смутило слово 'должен'. Но по сути, описано хорошее правило делать деструктор виртуальным в случае полиморфных типов. Можно использовать обычный деструктор, если вы точно уверены, как именно ваша иерархия классов будет использоваться или в целях оптимизации.


A>>хорошее правило — это 'не делать того что не нужно делать' или 'делать только то что нужно делать'.

A>>если виртуальный деструктор не нужен, то незачем его делать.

sts>в данном случае это надо делать (делать деструктор виртуальным), т.к. большинство разработчиков этого ожидают


большинство разработчиков (С++) не знают С++, не знают стандартную библиотеку и называет шаблоны магией, ну и что?
не надо равняться на таких людей.
In Zen We Trust
Re[8]: А когда может не вызываться деструктор?
От: Abyx Россия  
Дата: 25.01.13 20:14
Оценка: -1
Здравствуйте, sts, Вы писали:

A>>у термина "полиморфный (класс)" есть вполне конкретное определение.

A>>то что на это определение наложено ограничение, что объекты потомков такого класса будут удаляться через delete — это называется "более узкий смысл".

sts>ожидается, что деструктор будет полиморфным

sts>так же как ожидается, что из него не будет выкинуто исключение

*тобой* ожидается? да кого это волнует
In Zen We Trust
Re[5]: Разрушение компа прежде, чем будет разрушен объект, покатит? ;)
От: Erop Россия  
Дата: 25.01.13 21:01
Оценка:
Здравствуйте, sts, Вы писали:

sts>брутально, можно было никого не взрывать, а просто комп из розетки выдернуть

Это какой-то форс-мажор, на который не понятно, надо ли рассчитывать вообще при проектировании ПО для этого компа.

А вот на то, что ГЧ поразит таки цель, авторам её ПО рассчитывать стоит...

Впрочем, если тебя пугает брутальность, есть более мягкий вариант. Кроме БЧ есть много других устройств, в которых останов ПО не предусмотрен. То есть раз запущенное оно крутится на устройстве до конца его функционирования, либо до аппаратного сбоя/холодного рестарта. Там вызов дестукторов статических объектов обычно тоже не прежусмотрен,..
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[4]: А когда может не вызываться деструктор?
От: sts  
Дата: 26.01.13 11:07
Оценка:
Здравствуйте, sts, Вы писали:

A>>лечится включением предупреждений в компиляторе.


sts>что лечится ?

sts>если включить предупреждения, то деструктор вызовется ?
sts>не верю

с чем ты тут не согласен-то ?
Re[9]: А когда может не вызываться деструктор?
От: doarn Россия  
Дата: 26.01.13 13:33
Оценка:
Здравствуйте, Abyx, Вы писали:

sts>>ожидается, что деструктор будет полиморфным

sts>>так же как ожидается, что из него не будет выкинуто исключение

A>*тобой* ожидается? да кого это волнует


А какой профит делать публичный невиртуальный деструктор если vtbl уже есть в классе?
Я могу представить пару очень особенных случаев, но даже про них не уверен что оно того стоит.
Re[10]: А когда может не вызываться деструктор?
От: Abyx Россия  
Дата: 26.01.13 15:26
Оценка: -1
Здравствуйте, doarn, Вы писали:

D>Здравствуйте, Abyx, Вы писали:


sts>>>ожидается, что деструктор будет полиморфным

sts>>>так же как ожидается, что из него не будет выкинуто исключение

A>>*тобой* ожидается? да кого это волнует


D>А какой профит делать публичный невиртуальный деструктор если vtbl уже есть в классе?

D>Я могу представить пару очень особенных случаев, но даже про них не уверен что оно того стоит.

про "публичный" никто не говорил.
впрочем про то что его надо "делать" — тоже
In Zen We Trust
Re[2]: А когда может не вызываться деструктор?
От: Кодт Россия  
Дата: 26.01.13 18:55
Оценка:
Здравствуйте, Фаллопиева труба, Вы писали:

А>>Помогите новичку!

А>>Какие могут быть ситуации, когда не вызывается дестуктор(сделал new и не сделал delete не в счет)?

ФТ>Деструкторы могут не вызываться при создании массива с помощью оператора new[] и удалении его(массива) с помощью оператора delete.


Это называется "сделал new[] и не сделал delete[]"
Не считая того, что new[]/delete — это UB. (И одним из возможных эффектов этого поведения будет невызов деструкторов).

И кстати, мы говорим про new[] expression или про operator new[] ?
Перекуём баги на фичи!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.