C++ 全局对象构造和析构

*【注】此为小白引导教程


【引入】C++中的全局对象什么时候执行构造函数?什么时候执行析构函数?与局部对象又有什么区别?


【正文】

对于小白(我也是小白)来说,学习C++类的时候很容易联系之前的所学的全局对象,猜测全局对象和局部对象哪个先构造哪个后析构,与其百度,不如自己去问编译器!

思路是这样的,我们先写一个类,一个有点简单“又不简单”的类

#include <string>
#include <iostream>
using std::string;
using std::cout;
using std::endl;

class A
{
public:
    A(string s)
    {
        str.assign(s);
        cout << str << ":A构造" << endl;
    }
    ~A()
    {
        cout << str << ":A析构" << endl;
    }
private:
    string str;
};

我们写一个类用作局部和全局对象的类型,自然要知道在哪里构造在哪里析构,于是加了个string作为private成员记录位置。

类写好了开始写测试程序主体

A test1("全局");
int main()
{
    A test2("main");
    return 0;
}

编译执行,结果如图。
return 0;结果

可以发现,全局对象先于局部对象构造,后于局部对象析构。

我们可以扩展代码(以下代码无法编译通过)

/***************
以下代码无法编译通过
***************/
#include <string>
#include <iostream>
using std::string;
using std::cout;
using std::endl;

class A
{
public:
    A(string s)
    {
        str.assign(s);
        cout << str << ":A构造" << endl;
    }
    ~A()
    {
        cout << str << ":A析构" << endl;
    }
    string str;
};
//定义,假设不自动构造
A test1;
//构造
test1.A("全局");
int main()
{
    //定义,假设不自动构造
    A test2;
    //构造
    test2.A("main");
    //析构(主动式)
    test2.~A();
    return 0;
}
//析构(主动式)
test1.~A();

这样就便于理解了。

【扩展】

我们知道,在C/C++中结束程序不止有return,还有C stdlib.h中的exit(int)、abort(void),unistd.h中的_exit(int),C++的throw。
我们先来试下exit(int)

#include <stdlib.h>
int main()
{
    ...
    exit(0);
}

exit(0)结果

可以看到全局对象完整地构造析构,而main中的局部对象只完成了构造,未析构。

从exit(int)的特性来说,结果是正确的,exit(int)结束了main函数,并没有直接结束了程序,而全局对象储存在data数据段中由程序联立的运行时代码析构(对于小白来说姑且这么叫着)。

我们再来看_exit(0)

#include <unistd.h>
int main()
{
    ...
    _exit(0);
}

结果如图
_exit(0)结果

我们可以看出,不管是全局还是局部对象,都并未析构,说明_exit(int)是直接结束了程序的进程,并未抛出异常。

我们再来看看会抛出异常的abort()

#include <stdlib.h>
int main()
{
    ...
    abort();
}

结果如图
abort()结果
abort()返回值

可见abort()与_exit(int)的区别是会抛出异常!

好了,聊了这么久的C库函数,我们来看看C++的内置throw

int main()
{
    ...
    throw;
}

结果如图
throw结果
throw返回值

至此,我们都应该了解了C++中的全局对象什么时候执行构造函数,什么时候执行析构函数,与局部对象又有什么区别。
小白教程就是在文章最后作者并不会总结,小白自己总结去吧!

【题外话】
在学编程时,我们不能总是去百度,问大神,编译器才是最好的老师,得自己去写点代码试下,看看结果,再自己推下结论,哪怕错了都没关系,重要的不是结果是过程。这篇文章的精华不在正文内容而是在这题外话。


版权声明:本文为iyangyoulei原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。