1 Востаннє редагувалося ADR (19.02.2016 21:56:34)

Тема: C++ — чи є життя без try finally?

Я правильно зрозумів? У C++ немає конструкції try finally і жоден параметр його не добавить, але макроси вирішать цю проблему, правда ж?

Як взагалі можна писати програми без нього??


Приклад:

Змінюємо вміст форми
try {
    якщо бла бла то
        return
    ... 
    a = 0 / 0
    ...
} finally {
    відновити попередній стан форми
}


П.С. пора заводити твітер із переліком мінусів плюсів...

Прихований текст
  • Деструктор не є віртуальним по замовчуванню

  • overload і override не вказується явно. (хоча в Qt це, походу, виправлено)

  • конструкція try finally відсутня у стандарті

  • плюси компілюються цілу вічність

П.П.С Я лише почав вчити С++, так що мої звинувачення, скоріш за все, не є об'єктивними!

Подякували: leofun011

2 Востаннє редагувалося -=ЮрА=- (16.02.2016 08:57:10)

Re: C++ — чи є життя без try finally?

Деструктор не є віртуальним по замовчуванню

- тобто кожен класс повинен мати таблицю віртуальних функцій тим самим сповільнюючи роботу програми?

overload і override не вказується явно.

- мені складно уявити людину яка прагне писати побільше ключових слів, вам синеньке у коді подобається?

конструкція try finally відсутня у стандарті

- зробіть try{}catch і зробіть дії що стосуються очистки та відновенню кодом після catch
Рекомендую ознайомитись https://habrahabr.ru/company/pvs-studio/blog/239915/

Подякували: leofun011

3

Re: C++ — чи є життя без try finally?

Коли люди знаходять мінуси у плюсах, то здебільшого від недостатньої обізнанності в них.(без образ)

Подякували: 0x9111A1

4

Re: C++ — чи є життя без try finally?

ADR написав:

Я правильно зрозумів? У C++ немає конструкції try finally і жоден параметр його не добавить, але макроси вирішать цю проблему, правда ж?

Як взагалі можна писати програми без нього??

RAII же. Створюєте всі об'єкти, що треба знищити при виході, в області видимості. Якщо потрібен особливий new - робіть std::unique_ptr.

ADR написав:

Деструктор не є віртуальним по замовчуванню

А вам потрібне ключове слово nonvirtual для тих випадків, коли захочеться невіртуального?

ADR написав:

overload і override не вказується явно. (хоча в Qt це, походу, виправлено)

Вам хтось забороняє коментарі ставити? Компілятор і без них розбереться, що до чого, а для людини існують коментарі.

Подякували: leofun011

5

Re: C++ — чи є життя без try finally?

ADR написав:
Змінюємо вміст форми
try {
    якщо бла бла то
        return
    ... 
    a = 0 / 0
    ...
} finally {
    відновити попередній стан форми
}

Ви неправильно готуєте finally, бо воно зовсім не для того. Відновлювати форму треба в catch.

6

Re: C++ — чи є життя без try finally?

Деструктор не є віртуальним по замовчуванню

- тобто кожен класс повинен мати таблицю віртуальних функцій тим самим сповільнюючи роботу програми?

Маємо витік пам'яті:

class object1{
};

class object2 : public object1
{
    int* fild;
public:
   object2() { fild = new int(5);}
    ~object2() { delete fild; }
};

int main(int argc, char *argv[])
{
    object1* o = new object2;
    delete o;    
}

overload і override не вказується явно.

- мені складно уявити людину яка прагне писати побільше ключових слів, вам синеньке у коді подобається?

overload чи override? (я про те що легко помилитись)

class object1
{
public:
    virtual void method(int16_t a) { qDebug() << "object1"; }
};

class object2 : public object1
{
public:
    void method(int32_t a) { qDebug() << "object2"; }
};

int main(int argc, char *argv[])
{
    object1* o = new object2;
    o->method(0);
}

конструкція try finally відсутня у стандарті

- зробіть try{}catch і зробіть дії що стосуються очистки та відновенню кодом після catch

catch не лапає ретурни і я не хочу подавлювати помилку.

Рекомендую ознайомитись https://habrahabr.ru/company/pvs-studio/blog/239915/

ввечері подивлюсь, дякую

Коли люди знаходять мінуси у плюсах, то здебільшого від недостатньої обізнанності в них.(без образ)

Ви праві. Я лише почав вчити С++.

7

Re: C++ — чи є життя без try finally?

Я часто писав на Delphi типу:

WorkBeginEvent(WorkCount = count);
try
  for i := to count do
  begin
    SomeWork();
    WorkEvent(i);
   end;
finally
  WorkEndEvent()
end

Якщо події WorkEndEvent не буде то форма буде заблокована. І тут справа не у витоці пам'яті.
Як таке реалізувати?

8

Re: C++ — чи є життя без try finally?

ADR написав:

Як таке реалізувати?

Не писати на С++ на Delphi.

9

Re: C++ — чи є життя без try finally?

class Worker final
{
    public:

    Worker();
    ~Worker(){ось ваш WorkEndEvent}
    int someWork();
    void event( int count );
    static void hardWork( int workCount = count );
...
};
...
void Worker::hardWord( int workCount )
{
    Worker worker;
    for( int i = 0; i < count; ++i ) {
        worker.someWork();
        worker.event( i );
    }
}

Літер багато? Ну, як сказати - ви ж не давали визначення своїм функціям. Замість try/finally - проголошення класу.

Подякували: ADR1

10 Востаннє редагувалося ADR (16.02.2016 16:44:34)

Re: C++ — чи є життя без try finally?

koala написав:

Літер багато? Ну, як сказати - ви ж не давали визначення своїм функціям. Замість try/finally - проголошення класу.

Вони і не мають реалізації. Це події по яких змінюється стан форми/вікна:

WorkBeginEvent: procedure (Count: Integer) of object;
WorkEvent: procedure (Progress: Integer) of object;
WorkEndEvent: procedure () of object;
// упс... "Sender: TObject" пропустив

Пропонуєте кожен раз коли мені необхідно щоб якийсь код гарантовано виконався створювати об'єкт і писати це в деструкторі? Без сарказму.

11

Re: C++ — чи є життя без try finally?

quez написав:
ADR написав:
Змінюємо вміст форми
try {
    якщо бла бла то
        return
    ... 
    a = 0 / 0
    ...
} finally {
    відновити попередній стан форми
}

Ви неправильно готуєте finally, бо воно зовсім не для того. Відновлювати форму треба в catch.

Але ж мені її потрібно відновити в любому випадку.

12

Re: C++ — чи є життя без try finally?

ADR написав:
quez написав:
ADR написав:
Змінюємо вміст форми
try {
    якщо бла бла то
        return
    ... 
    a = 0 / 0
    ...
} finally {
    відновити попередній стан форми
}

Ви неправильно готуєте finally, бо воно зовсім не для того. Відновлювати форму треба в catch.

Але ж мені її потрібно відновити в любому випадку.

А можете пояснити ситуацію докладніше? Чому потрібно відновлювати форму і тоді, коли програма успішно виконалась, і тоді, коли вона упала?

13

Re: C++ — чи є життя без try finally?

ADR написав:

Пропонуєте кожен раз коли мені необхідно щоб якийсь код гарантовано виконався створювати об'єкт і писати це в деструкторі? Без сарказму.

Так. І в більшості випадків такий код і так прописаний у відповідних деструкторах: закрити файл, звільнити пам'ять etc. Тільки об'єкти треба створювати прив'язаними до місця виклику.

14

Re: C++ — чи є життя без try finally?

quez написав:
ADR написав:
quez написав:

Ви неправильно готуєте finally, бо воно зовсім не для того. Відновлювати форму треба в catch.

Але ж мені її потрібно відновити в любому випадку.

А можете пояснити ситуацію докладніше? Чому потрібно відновлювати форму і тоді, коли програма успішно виконалась, і тоді, коли вона упала?

Натискаєте кнопку "завантажити"
Форма блокується (чи просто LoadButton.Disable()) і відоражається прогрес бар завантаження
Завантаження
Форма розблоковується (LoadButton.Enable())
<виводиться помилка завантаження>

15

Re: C++ — чи є життя без try finally?

Чому не розблоковувати форму після блоку try-catch?

16

Re: C++ — чи є життя без try finally?

quez написав:

Чому не розблоковувати форму після блоку try-catch?

Бо обробка конкретно цієї виключної ситуації може відбуватися десь вище, а форму розблоковувати треба тут.

17

Re: C++ — чи є життя без try finally?

ADR написав:

Натискаєте кнопку "завантажити"
Форма блокується (чи просто LoadButton.Disable()) і відоражається прогрес бар завантаження
Завантаження
Форма розблоковується (LoadButton.Enable())
<виводиться помилка завантаження>

Створюється об'єкт "блок". При виході з функції (неважливо, якому) він знищується. Пропонуєте робити це без об'єктів?

18 Востаннє редагувалося quez (16.02.2016 17:24:51)

Re: C++ — чи є життя без try finally?

koala написав:
quez написав:

Чому не розблоковувати форму після блоку try-catch?

Бо обробка конкретно цієї виключної ситуації може відбуватися десь вище, а форму розблоковувати треба тут.

Ніхт ферштейн. Після catch може початись виконання в іншому місці?

19

Re: C++ — чи є життя без try finally?

quez написав:
koala написав:
quez написав:

Чому не розблоковувати форму після блоку try-catch?

Бо обробка конкретно цієї виключної ситуації може відбуватися десь вище, а форму розблоковувати треба тут.

Ніхт ферштейн. Після catch може початись виконання в іншому місці?

Ні, і в цьому і проблема.
Наприклад,

void f(){
  try {
    x();
  }
  finally {
    y();
  }
}
...
try{
  f();
}
catch( MyException &e) {
  Handle(e);
}

Якщо (зокрема, в x()) виникне MyException, то має бути виконано Handle. Якщо ж в замість finally буде catch(...), то буде виконано y(), але не Handle.

Подякували: ADR1

20

Re: C++ — чи є життя без try finally?

Підтримаю ADR: у випадку, коли у C# можна записати алгоритм п'ятьма рядками коду завдяки finally, у C++ треба створювати окремий клас та об'єкт. Це однозначно ускладнює сприйняття коду, робить його громіздким не надаючи якихось суттєвих переваг.
З іншого боку якщо ініціалізація і фіналізація трохи складніші за один виклик процедури, то тут уже краще застосовувати RAII. Але у C# та інших мов, які мають finally, із цим ніяких проблем нема.
В результаті робимо висновок, що не зважаючи на величезну кількість сміття, яку з плином часу затягли в C++, у ньому бракує деяких дуже корисних сьогодні концепцій. І їх уже не можна з легкістю туди запхнути. Нічого дивного, що Swift, Go, Rust та інші альтернативи набирають популярності.

Подякували: ADR1