程序终止¶
c++
程序终止方式共有3
种
- 调用
exit
- 调用
abort
- 在
main
函数调用return
表达式
exit¶
参考:
声明在头文件stdlib.h
,其参数值作为程序返回代码或退出代码。按照惯例,返回0
表示成功退出
void exit (int status);
在stdlib.h
中定义了两个返回代码常量:
/* We define these the same for all machines.
Changes from this to the outside world should be done in `_exit'. */
#define EXIT_FAILURE 1 /* Failing exit status. */
#define EXIT_SUCCESS 0 /* Successful exit status. */
在main
函数使用return
语句等同于使用返回值作为参数调用exit
函数
abort¶
参考:
声明在头文件stdlib.h
,函数abort
表示终止C++
程序
void abort() noexcept;
其和exit
函数的区别在于
exit
函数允许运行时终止进程(run-time termination processing
)发生(将会调用全局对象析构函数)abort
函数立即终止程序
return¶
参考:return Statement in Program Termination (C++)
功能上和exit函数相同
退出注意事项¶
参考:
- 构造:全局对象(
global object
)在main
函数执行前进行构造 - 退出:在执行
exit
或者return
语句后,按相反顺序执行析构函数
如果执行abort
函数,就不会调用对象的析构函数
示例代码¶
#include <iostream>
#include <cstring>
#include <array>
using std::cout;
using std::endl;
class ShowData {
public:
// Constructor opens a file.
ShowData(const char *szDev) {
filename = szDev;
cout << "construct: " << filename << endl;
OutputDev = fopen(szDev, "w");
}
// Destructor closes the file.
~ShowData() {
cout << "destruct: " << filename << endl;
fclose(OutputDev);
}
// Disp function shows a string on the output device.
void Disp(char *szData) {
fputs(szData, OutputDev);
}
private:
FILE *OutputDev;
const char *filename;
};
ShowData sd3 = "sd3";
ShowData sd4 = "sd4";
int main() {
cout << "begin" << endl;
ShowData sd1 = "sd1";
ShowData sd2 = "sd2";
sd1.Disp("hello to default device\n");
sd2.Disp("hello to file hello.dat\n");
sd3.Disp("hello to sd3");
sd4.Disp("hello to sd4");
cout << "end" << endl;
// abort();
return 0;
}
注意:上面代码中全局对象的定义顺序
结果
construct: sd3
construct: sd4
begin
construct: sd1
construct: sd2
end
destruct: sd2
destruct: sd1
destruct: sd4
destruct: sd3
atexit¶
参考:
在调用全局对象的析构函数之前会调用atexit函数
如果对程序指定了多个atexit
函数,则它们都将以栈的形式按相反顺序执行(即最后一次调用将第一个执行)
示例如下:
...
...
void f() {
cout << "quickly, exit will happen" << endl;
}
int main() {
cout << "begin" << endl;
ShowData sd1 = "sd1";
ShowData sd2 = "sd2";
sd1.Disp("hello to default device\n");
sd2.Disp("hello to file hello.dat\n");
sd3.Disp("hello to sd3");
sd4.Disp("hello to sd4");
cout << "end" << endl;
atexit(f);
return 0;
}
结果
construct: sd3
construct: sd4
begin
construct: sd1
construct: sd2
end
destruct: sd2
destruct: sd1
quickly, exit will happen
destruct: sd4
destruct: sd3
abort¶
参考:Using abort
调用abort函数中止程序不仅会绕过局部和全局对象的析构函数,还会绕过atexit
函数的调用,示例如下:
...
atexit(f);
abort();
return 0;
}
结果:
construct: sd3
construct: sd4
begin
construct: sd1
construct: sd2
end
只有构造函数,没有析构函数了