Как закончить код на C++



Я хотел бы, чтобы мой код C++ перестал работать, если выполняется определенное условие, но я не уверен, как это сделать. Так что просто в любой момент, если if оператор true завершает код следующим образом:



if (x==1)
{
kill code;
}
607   14  
c++

14 ответов:

есть несколько способов, но сначала вам нужно понять, почему очистка объекта важна, и, следовательно, причина std::exit маргинализируется среди программистов на C++.

RAII и стека размотки

C++ использует идиому под названием RAII, что в простых терминах означает, что объекты должны выполнять инициализацию в конструкторе и очистку в деструкторе. Например,std::ofstream класс [может] открыть файл во время конструктора пользователь выполняет над ним операции вывода, и, наконец, в конце его жизненного цикла, обычно определяемого его областью действия, вызывается деструктор, который по существу закрывает файл и сбрасывает любое записанное содержимое на диск.

что произойдет, если вы не доберетесь до деструктора, чтобы сбросить и закрыть файл? кто знает! но, возможно, он не будет записывать все данные, которые он должен был записать в файл.

например, рассмотреть этот код

#include <fstream>
#include <exception>
#include <memory>

void inner_mad()
{
    throw std::exception();
}

void mad()
{
    std::unique_ptr<int> ptr(new int);
    inner_mad();
}

int main()
{
    std::ofstream os("file.txt");
    os << "Content!!!";

    int possibility = /* either 1, 2, 3 or 4 */;

    if(possibility == 1)
        return 0;
    else if(possibility == 2)
        throw std::exception();
    else if(possibility == 3)
        mad();
    else if(possibility == 4)
        exit(0);
}

что происходит в каждой возможности-это:

  • возможность 1: Return по существу оставляет текущую область действия функции, поэтому он знает о конце жизненного цикла os таким образом, вызывая его деструктор и делая правильную очистку путем закрытия и промывки файла на диск.
  • вариант 2: выбрасывание исключения также заботится о жизненном цикле объектов в текущей области, тем самым делая правильная уборка...
  • вариант 3: здесь стека размотки вступает в действие! Даже если исключение бросается на inner_mad, размотчик будет идти, хотя стек mad и main для выполнения надлежащей очистки, все объекты будут уничтожены должным образом, в том числе ptr и os.
  • возможность 4: Ну что, здесь? exit это функция C, и она не знает и не совместима с идиомами C++. Это не выполните очистку объектов, включая os в том же объеме. Таким образом, ваш файл не будет закрыт должным образом, и по этой причине содержимое может никогда не попасть в него!
  • Другие Возможности: он просто оставит основную область, выполнив неявное return 0 и, таким образом, имеет тот же эффект, что и возможность 1, т. е. Правильная очистка.

но не будьте так уверены в том, что я только что сказал вам (в основном возможности 2 и 3); продолжить чтение, и мы узнаем, как выполнить правильную очистку на основе исключений.

Возможные Способы конец

возвращение из главного!

вы должны делать это всякий раз, когда это возможно; всегда предпочитайте возвращаться из своей программы, возвращая правильный статус выхода из main.

вызывающий вашу программу и, возможно, операционную систему, возможно, захочет узнать, что ваша программа должна была сделать выполнена успешно или нет. По этой же причине вы должны вернуть либо ноль, либо EXIT_SUCCESS сигнализировать, что программа успешно завершена и EXIT_FAILURE чтобы сигнализировать о неудачном завершении программы, любая другая форма возвращаемого значения определяется реализацией (§18.5/8).

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

[не] бросить исключение

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

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

Как упоминал Мартин Йорк, exit не выполняет необходимую очистку, как это делает return.

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

рассмотрим следующий пример. Со следующей программы будет создан файл с указанным содержимым. Но если return прокомментирован и раскомментирован exit (0), компилятор не гарантирует, что файл будет иметь обязательный текст.

int main()
{
    ofstream os("out.txt");
    os << "Hello, Can you see me!\n";
    return(0);
    //exit(0);
}

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

вызов std::exit.   

люди говорят " вызов exit (код возврата)", но это плохой тон. В небольших программах это нормально, но есть ряд проблем с этим:

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

действительно, единственный раз, когда вы должны выйти из проблемы, это с этой строкой главный.cpp:

return 0;

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

return 0; положите это везде, где вы хотите в пределах int main() и программа сразу же закроется.

либо верните значение из вашего main или использовать

программа завершится, когда поток выполнения достигнет конца основной функции.

чтобы завершить его до этого, вы можете использовать функцию exit(int status), где status-это значение, возвращаемое тому, что запустило программу. 0 обычно указывает на состояние без ошибок

Если у вас есть ошибка где-то глубоко в коде, то либо бросить исключение или установить код ошибки. Всегда лучше создать исключение вместо установки кодов ошибок.

как правило, вы должны использовать exit() метод с соответствующим код.

ноль будет означать успешный запуск. Ненулевое состояние указывает на то, что произошла какая-то проблема. Этот код выхода используется родительскими процессами (например, скриптами оболочки) для определения успешного выполнения процесса.

помимо вызова exit (error_code) - который вызывает обработчики atexit, но не деструкторы RAII и т. д. - все больше и больше я использую исключения.

все больше и больше моя основная программа выглядит так:

int main(int argc, char** argv) 
{
    try {
        exit( secondary_main(argc, argv );
    }
    catch(...) {
        // optionally, print something like "unexpected or unknown exception caught by main"
        exit(1);
    }
}

где secondary_main там, где все вещи, которые были первоначально помещены -- т. е. исходный main переименовывается secondary_main, а заглушка main выше добавляется. Это просто тонкость, так что между лотком и уловом в основном не слишком много кода.

Если вы хотите, поймать другие типы исключений.
Мне очень нравится ловить строковые типы ошибок, как std::string или char* и печатать в обработчике catch в main.

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

в целом, c обработка ошибок-выход и сигналы-и C++ обработка ошибок-try/catch / throw исключения-играть вместе непоследовательно на лучший.

затем, где вы обнаружите ошибку

throw "error message"

или какой-то более конкретный тип исключения.

чтобы нарушить условие, используйте return (0);

Так, в вашем случае это будет:

    if(x==1)
    {
        return 0;
    }

Если ваш оператор if в цикле вы можете использовать

 break; 

Если вы хотите избежать какой-то код и продолжать цикл использования:

продолжить;

Если ваш оператор if не в цикле вы можете использовать:

 return 0;

Or 




  exit();

чувак... exit() функция определена в stdlib.h

поэтому вам нужно добавить препроцессор.

поставить include stdlib.h в секции заголовка

затем использовать exit(); везде, где вам нравится, но не забудьте поставить номер интергера в скобках выхода.

например:

exit(0);

Если условие, которое я тестирую, действительно плохие новости, я делаю это:

*(int*) NULL= 0;

Это дает мне хороший coredump, откуда я могу изучить ситуацию.

Comments

    Ничего не найдено.