LINUX.ORG.RU

Деструкторы не нужны (?)

 


0

5

Тут в соседней теме один анон сказанул следующее:

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

Собственно, хотелось бы поговорить о выделенном.

Антон прикрылся ссылкой, по которой про деструкторы я так ничего и не нашёл. Более того, в твиттере Кармака всё выглядит с точностью до наоборот — https://twitter.com/id_aa_carmack/status/172340532419375104

RAII constructor / destructor pairing and templates for type safe collections are pretty high on my list of C++ benefits over C

Кто прав? Кто виноват? И нужны ли в итоге C++ деструкторы?

Ответ на: комментарий от dzidzitop

меня больше интересует как потом гарантированно проверить этот сохранённый эксэпшин

А как гарантированно проверить suppressed exceptions в Java? Тоже никак, чудес не бывает.

я вижу в этом случае большой кусок спагетти-кода.

Как и в Java.

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

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

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

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

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

Я с тобой абсолютно согласен. А теперь расскажи - как часто ты проверяешь наличие подавленных исключений в своем коде на Java.

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

При том, что единственный ресурс, который может захватывать и освобождать твой Transzaction это refcounter соединения к базе.

Ну вот ты и признал, что RAII на классах с деструкторами неуместно использовать для освобождения удалённых ресурсов :-) Весь RAII в цепепе годится лишь для «установить флажок в переменной» или поменять значение счётчика или выполнить delete/free :-) На этом техника «захват ресурса - есть инициализация» в цепепе заканчивается :-) Я то это и так знал, но теперь вот ещё и ты признался :-)

Считать транзакцию ресурсом, а тем более COMMIT, where all the hard work starts, освобождением ресурса мог только обколотый скобками лишпер.

Так в лишпе можно такую абстракцию как Transaction без проблем сделать :-) Это тебе не цепепе :-)

Не продемонстрировал.

Да там выше посмотри, ты просто не нашёл :-)

Кто тебе такую чушь сказал?

Страуструп, Саттер, Мейеc :-) Напиши им, что это всё чушь и что у тебя компилятся деструкторы с throw :-) Лол :-)

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

Ну вот ты и признал, что RAII на классах с деструкторами неуместно использовать для освобождения удалённых ресурсов

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

Страуструп, Саттер, Мейеc

Мне показалось что ты хоть немного, но не туп. Оказывается, всё, что у тебя есть из аргументов — это отсылка к аффтаритетам.

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

Может быть вы напишете более простой пример?

Да тут важен принцип: MultiIndex — это контейнер, в котором доступ к объекту можно получать по разным ключам. Для совсем простого примера можно взять объект:

struct A {
  std::string a_;
  std::string b_;
};
И попробовать написать контейнер multi_index_A:
class multi_index_A {
public :
  void emplace(std::string a, std::string b);
  const A * find_by_a(const std::string & key) const;
  const A * find_by_b(const std::string & key) const;
  void erase_by_a(const std::string & key);
  template< typename It > void erase_by_a(It begin, It end);
  void erase_by_b(const std::string & key);
  template< typename It > void erase_by_b(It begin, It end);
};
В простом случае такой multi_index_A реализуется через два std::map-а:
class multi_index_A {
  using A_shptr = std::shared_ptr<A>;
  std::map<std::string, A_shptr> index_a_;
  std::map<std::string, A_shptr> index_b_;
public :
  ...
};
А методы erase_by_a и erase_by_b вынуждены удалять объект сначала из одного контейнера, затем из другого.

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

Попробуйте сделать то же самое для случая с исключениями из деструкторов. И чтобы хоть какие-то гарантии exception safety обеспечивались.

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

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

Аминь. А с меня, пожалуй, хватит.

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

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

Ты ещё и балабол :-) Чего стоят твои эти слова? :-) Лол :-)

Вот твои заявления, где ты не считаешь транзакцию ресурсом:

При том, что единственный ресурс, который может захватывать и освобождать твой Transzaction это refcounter соединения к базе.
Считать транзакцию ресурсом, а тем более COMMIT, where all the hard work starts, освобождением ресурса мог только обколотый скобками лишпер.

Ты ведь не считаешь её ресурсом лишь потому, что тебе твой любимый цепепе руки выкручивает :-) А так это самый что ни есть ресурс, удалённый ресурс :-) Так что ты не сотрясай воздух зря :-)

Мне показалось что ты хоть немного, но не туп. Оказывается, всё, что у тебя есть из аргументов — это отсылка к аффтаритетам.

Аффтаритеты дают аргументацию почему так делать нельзя :-) А ты просто компилишь деструкторы с throw и балаболишь :-)

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

Попробую пояснить. Специальным случаем является не кидание bad_alloc'а, а реальная нехватка памяти для объекта-исключения(что, кстати, делает C++ в этом случае?). В этом случае нужно сигнализировать bad_alloc'ом. Память под bad_alloc резервируется. Кидать два bad_alloc'а на данный момент бессмысленно(в нем нет информации, делающий такой ход полезным).

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

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

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

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

«не пишите на С++» и на этом завершать диалог.

Отличная мысль :-)

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

я вообще не рассматриваю бред обжабаных. тем более такой люто тупой бред.

Мне вообще пофигу на язык программирования. А Java я не использую от слова совсем. Более того, C++ мой основной язык.

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

Ты ведь не считаешь её ресурсом лишь потому, что тебе твой любимый цепепе руки выкручивает

Вроде я уже писал про это, но... ты дальше продолжаешь подтверждать свою невменяемость.

Транзакцию надо завершать по разному в зависимости от того, возникли ли в скоупе с этой транзакцией исключения или нет.

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

А ты просто компилишь деструкторы с throw и балаболишь

Я просто компилирую деструкторы с throw когда это необходимо. В отличие от тебя, я думаю головой, а не лозунгами «из деструкторов нельзя бросать исключения».

Аффтаритеты дают аргументацию почему так делать нельзя

Майерсы и проч. — это нулевое приближение к техникам использования цепепе. Перед собеседованием на джуна разве что почитать.

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

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

А можно кодом?

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

man boost serialize

Который не совместим между версиями - это раз. И я эстетически не очень одобряю свободные функции - это два. Пытаюсь их избегать если это возможно. Они не делают код более очевидным уж точно.

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

я эстетически не очень одобряю свободные функции

ЛООООООООООООООЛ. И при этом эстетически одобряешь фактическое наследование интерфейса от реализации...

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

Грубо говоря, вот так (на качество не претендую):

void erase_by_a(const std::string & key) {
  auto it = index_a_.find(key);
  if(it != index_a_.end()) {
    index_b_.erase(it->second->b_);
    index_a_.erase(it);
  }
}
template< typename It > void erase_by_a(It begin, It end) {
  for(; begin != end; ++begin) {
    auto it = index_a_.find(*begin);
    if(it != index_a_.end()) {
      index_b_.erase(it->second->b_);
      index_a_.erase(it);
    }
  }
}

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

Вроде я уже писал про это, но... ты дальше продолжаешь подтверждать свою невменяемость.

В чём невменяемость? :-)

Транзакцию надо завершать по разному в зависимости от того, возникли ли в скоупе с этой транзакцией исключения или нет.

Ну и пожалуйста :-) Кто против? :-) Есть потуга под названием std::uncaught_exception(), только она проблему не решает :-) Тут речь про деструкторы, а не про лекции по транзакциям :-)

Могу признаться в одном: я сделал большую ошибку, заговорив с неадекватом, который собрался делать безусловный COMMIT.

Да не важно какой COMMIT, std::uncaught_exception() в руки тебе и проверяй :-) Важно что в случае фейла самой команды COMMIT об этом нельзя сообщить через исключения :-)

Я просто компилирую деструкторы с throw когда это необходимо. В отличие от тебя, я думаю головой, а не лозунгами «из деструкторов нельзя бросать исключения».

Ну у себя на localhost все герои :-) Можно и не такое делать :-)

Майерсы и проч. — это нулевое приближение к техникам использования цепепе. Перед собеседованием на джуна разве что почитать.

И проч. - это Страуструп с Саттером, которых я упомянул? :-) Кого же ты читал тогда? :-) Лол :-)

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

И при этом эстетически одобряешь фактическое наследование интерфейса от реализации...

Ты о чем вообще болезный?

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

Где ты вообще увидел наследование интерфейса от реализации? Покажи пальцем, у тебя какие-то валжные фантазии и ты читаешь чужие слова наискосок и понимаешь в них, что сам хочешь в них увидеть. Это болезнь!

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

std::uncaught_exception()

std::uncaught_exceptions() завезли везде, куда могли

Кого же ты читал тогда?

Если бы про это можно было где-то прочитать... Ситуация такая же, как с научным мышлением: никаких методичек нет, всё надо самому нарабатывать.

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

Важно что в случае фейла самой команды COMMIT об этом нельзя сообщить через исключения

Хозяин — барин. Если ты для по каким-то религиозным соображениям решил, что никак нельзя — значит нельзя.

Только не надо язык винить. Не тот случай.

anonymous
()
Ответ на: комментарий от utf8nowhere
class MyFormatReader {};
class MyFormatWriter {};

struct ISerial
{
	virtual  void ReadData(MyFormatReader&) = 0;
	virtual  void WriteData(MyFormatWriter&) = 0;
};

class Vector {};

struct Data {};

class SerialVector : public Vector, public ISerial
{
public:
	virtual  void ReadData(MyFormatReader&)
	{

	}

	virtual  void WriteData(MyFormatWriter&)
	{

	}

};

void FillVector(Vector& v)
{

}

Data Serialize(ISerial& ser)
{
	return Data();
}

int main()
{
	SerialVector v;
	FillVector(v);
	auto data = Serialize(v);
        return 0;
}

где тут наследование интерфейса от реализации лолушка?

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

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

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

Только не надо язык винить. Не тот случай.

Случай как раз тот самый, когда стоит показать недостатки :-)

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

Да и что за взгляд, в шарпе такое вполне катит, даже поощряется.

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

Случай как раз тот самый, когда стоит показать недостатки

Ещё раз: у тебя не получилось привести пример, демонстрирующий недостатки языка.

Пойми, фанатик: мне интересны недостатки. Только ты осиль показать их.

Если хочешь показать «как надо», приведи свою скобкоту на лишпе.

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

Ещё раз: у тебя не получилось привести пример, демонстрирующий недостатки языка.

Шо, опять? Вам сколько не приводи, все равно будете твердить что их нет и вообще вывсеврети. Плавали, знаем.

мимокрокодил

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

С++ — это мультпарадигменный язык, здесь нужно сочетать и ООП, и обычный процедурный подход. Результат (с точки зрения C++) будет получаться лучше, чем если придерживаться какой-то одной крайности. А вот в Eiffel или C#, там свободы выбора меньше. Там другие подходы работают.

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

Ещё раз: у тебя не получилось привести пример, демонстрирующий недостатки языка.

Получилось показать, что RAII не панацея :-) Конечно, фанатикам это может быть не нравится, но это так :-)

Пойми, фанатик: мне интересны недостатки. Только ты осиль показать их.

Хахаха :-) Пойми, что деструкторы, оказывается, не очень то и нужны :-) Это если по теме :-) Лол :-)

Если хочешь показать «как надо», приведи свою скобкоту на лишпе.

Хочу лишь продемострировать недостатки цепепе :-)

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

Вам с таким взглядом на жизнь прямиком в Eiffel надо. Там именно так все и делают.

Вообще-то это один из Ъ-С++ стилей. Надо расширять кругозор.

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

в лиспе

Хочется пошутить про некрофилию но как-то жалко лисперов. У них и исключения в деструкторах и весь фарш а все равно лисп ненужен

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

Хочется пошутить про некрофилию но как-то жалко лисперов.

У тебя не получится пошутить, ведь ты лиспа, наверняка, не знаешь :-) Потому что если бы знал, то не говорил бы про

У них и исключения в деструкторах и весь фарш а все равно лисп ненужен

:-) Поэтому пошути про деструктор ~QWidget в Qt :-)

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

Вот уж где бесполезно искать Ъ-стиль, так это в C++. Пора бы уже знать об этом.

Я не зря написал «один из». И COM плюс его наследие не пустое место в истории С++.

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

как такое может быть?

Сетевой ресурс больше не отвечает, например. Буфер записи записать не удаётся.

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

Поэтому пошути про деструктор ~QWidget в Qt :-)

Окей. У программистов на c++ есть qt а у программистов на лиспе есть лисп

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

Окей. У программистов на c++ есть qt а у программистов на лиспе есть лисп

Да, поэтому у программистов на лиспе есть commonqt, а вот обратное неверное :-)

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

Вам сколько не приводи

Пока был только один раз. Или ты считаешь, что если привести несколько раз один и тот же пример, то это считается за несколько примеров?

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

Да, поэтому у программистов на лиспе есть commonqt,

Устаревшие обертки (QT5 is not yet supported), битые ссылки, отсутствие нормальной документации и примеров (а значит идти по граблям и узнавать, что не поддерживается или криво сделано, предлагается пользователю) - да, это всегда есть у программистов на лиспе. Еще можно сравнить качество библиотек. Вот лисп (пример взят по ссылке):

(defclass canvas ()
    ()
  (:metaclass qt-class)
  (:qt-superclass "QWidget")
  (:override ("paintEvent" paint-event)))

(defmethod paint-event ((this canvas) paint-event)
  (declare (ignore paint-event))
  (let ((painter (#_new QPainter this)))
    (#_end painter)))

Вот питон:

class Canvas(QWidget):

    def paintEvent(self, event):
        qp = QPainter(self)

No comments.

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

Какой унылый ужас.

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

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

Вот именно. У программистов лиспе есть bindibgи к qt, написаном на ужасном и плохом c++.

А вот программистам на c++ питон ненужен. Потому что неуловимый Джо.

Ну чувак, серьезно. Я понимаю что у тебя бомбит но нам сратье

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

конкретно на жабе это будет просто много вложенных finally.

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

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

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

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

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