LINUX.ORG.RU

Почему не вызывается деструктор если объект не был сконструирован(с++)

 


0

1

Добрый день, подскажите, как это все внутри устроено? Т.е. если конструктор отрабатывает от начала до конца то где-то флаг устанавливается и впоследствии вызывается деструктор? Т.е. во время работы программы должна быть некая таблица? И есть ли разница где будет выброшено исключение: например это может быть один из членов класса.



Последнее исправление: cetjs2 (всего исправлений: 1)

Никаких флагов нет, если не использовать дополнительные механизмы вроде std::optional. Деструктор всегда вызывается при удалении объекта.

X512 ★★★★★
()

Для каждого места в коде конструктора компилятор знает, что к этому моменту проинициализировано, и какие деструкторы надо вызывать. Таблица действительно есть, она связывает код конструктора с обработчиками исключений. Когда где-то происходит исключение, начинается процесс раскрутки стека, во время которого с этой таблицей сверяются, чтобы вызывать правильные обработчики, которые вызывают нужные деструкторы.

Все детали для Itanium ABI можно почитать тут: https://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html

ilammy ★★★
()

объект не был сконструирован(с++)

Это как? Ты создаешь объект с помощью malloc? Или как ты умудрился создать объект без запуска конструктора? Код давай.

A_Stahl
()

Объект типа class создаются только с использованием new().

Код покажите.

Владимир

anonymous
()

Время жизни объекта начинается, как только отработал хотя бы один конструктор. Когда время жизни объекта заканчивается вызывается деструктор.

fsb4000 ★★★★★
()
Ответ на: комментарий от anonymous

Если вы использовали malloc для создания объекта, то «без бутылки не разберешься».

anonymous
()
Ответ на: комментарий от A_Stahl

Это как? Ты создаешь объект с помощью malloc? Или как ты >>умудрился создать объект без запуска конструктора? Код давай.

Да просто допустим в конструкторе выкидываю какое-нибудь исключение.

da17
() автор топика
Ответ на: комментарий от Dudraug

Я думаю автор спрашивает про это, но это не точно.

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

da17
() автор топика
Ответ на: комментарий от da17

но вот у вас получается деструктор вызываетя.

Деструктор A не вызывается, вызывается только деструктор Aint.

X512 ★★★★★
()
Ответ на: комментарий от da17

деструктор вызывается только тогда когда конструктор полностью отработал.

деструктор вызывается, когда отработал любой из конструкторов.

Посмотрите внимательно на классы Test и Test2:

https://gcc.godbolt.org/z/TTM9be

fsb4000 ★★★★★
()
Ответ на: комментарий от fsb4000

Да, заметил, что не вызывается.

da17
() автор топика
Ответ на: комментарий от anonymous

Свалил бы ты в тред к метаобезьянкам по разуму.

anonymous
()

Деструктор вызывается только для объектов которые были созданы. Если из конструктора выбрасывается исключение, то объект не был создан, значит и деструктор не будет вызван. Ты сам ответственен за управление ресурсами в такой ситуации.

Выбрасывать исключения из конструкторов и деструкторов - это направлять оружие себе в ногу, так обычно не делают.

anonymous
()
Ответ на: комментарий от anonymous

Деструктор вызывается когда объект уничтожается, если объект не был создан, то он и уничтожаться не будет. Ты понял о чем речь? Никаких таблиц в программе нет, объект создается либо в стеке, либо на куче, либо в статической памяти, уничтожается в соответствии с правилами для этой области памяти.

anonymous
()
Ответ на: комментарий от anonymous

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

Нет, для тех, чей лайфтайм начался. И между созданием объекта и началом его лайфтайма есть разница.

anonymous
()
Ответ на: комментарий от A_Stahl

Просвещайся

как ты умудрился создать объект без запуска конструктора?

struct C { int m; };

int main()
{
    int i; // создал объект без запуска конструктора
    C c { 0 }; // создал объект без запуска конструктора
}
anonymous
()
Ответ на: комментарий от anonymous

Никаких таблиц в программе нет, объект создается либо в стеке, либо на куче, либо в статической памяти, уничтожается в соответствии с правилами для этой области памяти.

Ну и как статические объекты уничтожаются в обратном порядке без никаких таблиц? Причём уничтожаются только те, которые были сконструированы.

anonymous
()

template, class и STL, … - гроб C++.

Давно от их использования отказался и разработал свою объектную модель.
Все ok!

Много раз говорил на форуме о том, что class в C++ является всего лишь одной из возможных архитектур объектов в C++.

Ограничение на ограничениях и ограничениями все погоняет - ужас!
А потом для этого «ужаса» плодят стандарты.

И что удивительно - рады и «щеки надувают» от знания «современного» C++.

Владимир

anonymous
()
Ответ на: комментарий от anonymous

Давно от их использования отказался и разработал свою объектную модель. Все ok!

Давай показывай. Подозреваю, что всё работает в рантайме без проверок типов и с тормозами.

Альтернативы классам с методами без тормозов с технической точки зрения не существует. Объектные модели в Си по сути делают тоже самое, но вручную, а C++ умеет автоматически генерировать vtable и проверять типы в compile time.

X512 ★★★★★
()
Последнее исправление: X512 (всего исправлений: 1)
Ответ на: комментарий от X512

Подозреваю, что всё работает в рантайме без проверок типов и с тормозами.

Да вы правы. Все очень плохо, тормознуто, …

Не о чем говорить.

Владимир

anonymous
()
Ответ на: комментарий от X512

Альтернативы классам с методами без тормозов с технической точки зрения не существует. Объектные модели в Си по сути делают тоже самое, но вручную, а C++ умеет автоматически генерировать vtable и проверять типы в compile time.

Let it be.

Владимир

anonymous
()
Ответ на: Просвещайся от anonymous

Просвещайся

С каких это пор int слал объектом? Ты уверен, что при создании структуры не вызовется конструктор по умолчанию? Я вот нет…

A_Stahl
()
Ответ на: комментарий от A_Stahl

С каких это пор int слал объектом?

Всегда был, лол.

Ты уверен, что при создании структуры не вызовется конструктор по умолчанию?

Уверен.

Я вот нет…

На то ты и неуч.

anonymous
()
Ответ на: комментарий от anonymous

Чё ты в меня ссылками на хабрапомойку кидаешься? Я по помойкам не лажу.

Есть что умного сказать — говори. (Но у тебя нет ничего).

anonymous
()
Ответ на: комментарий от anonymous

Чё ты в меня ссылками на хабрапомойку кидаешься? Я по помойкам не лажу

Да это не вам ответ был.
У вас был приведен пример инициализации.
Вот и решил добавить «5 копеек от себя».
Не все на habr «помойка», но и «помоев» - МНОГО.

Владимир

anonymous
()
Ответ на: комментарий от anonymous

Да это не вам ответ был.

Технически был мне.

Но раз так — пардон за наезд.

anonymous
()
Ответ на: комментарий от Lzzz

Да вообще то конечно мое суждение не совершенно.
Исходил из того, что ТС объекты создает с использованием malloc.
Они создаются …, но потом интересные коллизии возникают /и не всегда/.

Владимир

anonymous
()
Ответ на: комментарий от A_Stahl

Ты создаешь объект с помощью malloc

Объекты нельзя создать с помощью malloc. Выделить память под размер объекта – можно, создать – нет. Для создания объекта по адресу используется placement new.

Siborgium ★★★★★
()
Ответ на: комментарий от Lzzz

так например работает emplace_back(). память выделяется контейнером, а объект инициализируется конструктором в памяти которую выделил контейнер. выделение памяти и инициализация объекта разделены.

anonymous
()
Ответ на: комментарий от da17

но вот у вас получается деструктор вызываетя

Не вызывается же.

Dudraug ★★★★★
()
Ответ на: комментарий от I-Love-Microsoft

Так можно делать? В смысле, законно прилично?

ты же вроде на Qt пишешь, а там любой Widget у которого есть дети кидает исключения из конструктора. (new кидает bad_alloc при неудаче)

fsb4000 ★★★★★
()
Ответ на: комментарий от fsb4000

А я сегодня еще прочитал, что из конструкторов можно вызывать любые ф-ии и даже сами конструктор, т.е. я могу и деструктор в конструкторе вызвать получается?

da17
() автор топика
Ответ на: комментарий от fsb4000

Тут мне конечно идеология языка не понятна. Если так можно делать, значит это нужно кое-где или можно делать все что не запрещено, а господь уж сам разберется как это и зачем должно работать.

da17
() автор топика
Ответ на: комментарий от da17

Если так можно делать, значит это нужно

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

https://gcc.godbolt.org/z/bWM3h7

Как видно в примере, для класса в union деструктор не вызывается, и нужно вызывать самостоятельно.

Нечто похожее делают реализаторы стандартной библиотеки компилятора для std::variant.

fsb4000 ★★★★★
()
Последнее исправление: fsb4000 (всего исправлений: 1)
Ответ на: комментарий от da17

конструктор и деструктор - это такие же методы класса как и все остальные, просто они вызываются автоматически и поэтому особенные. методы класса - это обычные функции, но им неявно передаётся указатель на объект. всё так же как в других языках.

если у тебя вопросы в стиле: «доктор, мне больно когда я стреляю себе в ногу», то ты явно лезешь туда куда тебе лезть не надо. просто игнорируй эту часть. с++ мультипарадигменный язык, в нём есть много чего, но тебе не обязательно использовать весь набор парадигм, и это даже часто вредно использовать весь набор парадигм, такая фигня получается.

anonymous
()
Ответ на: комментарий от anonymous

это не ub. ub - это если в спеке написано, что это ub, всё остальное - это не ub.

anonymous
()
Ответ на: комментарий от da17

типичный случай когда из конструктора вызывается конструктор:

class file {
  file(int descriptor) : desc(descriptor) {}
  file(const char *filename) : file(open(filename)) {}

  int descriptor = -1;
}

ты походу всё таки не понял, что конструктор - это метод который вызывается когда объект создаётся, а деструктор - это метод который вызывается когда объект уничтожается. это полное описание конструктора и деструктора, всё остальное про конструктор и деструктор ты додумал сам.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.