C++对象的生命周期详细解读
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
前言
我们写C++就不可避免需要用到变量,用到变量就要知道生命周期原则,要不然写的代码自带bug,崩盘只是迟早的事。
一、什么是生命周期?
生命期顾名思义就是出生到死亡的这个时间。放到C++的对象上就是从对象被创建开始到对象被回收结束这么一个过程。
二、对象类型
前面已经说了生命周期是相对于对象来说的,要讲解生命期必须围绕着对象的类型来说,不同类型的对象生命期是完全不一样的。
1.局部对象(local object)
又称自动对象(automatic object),在程序执行到对象定义的位置时创建,在程序执行到对象的作用域末尾时被回收。
代码如下(示例):
#include <iostream>
class Demo {
public:
Demo() { std::cout << "Demo" << std::endl; }
~Demo() { std::cout << "~Demo" << std::endl; }
};
void test() {
Demo d;//对象定义的位置
}
int main() {
test();
}
为了方便演示,增加了自定义构造和析构。
执行结果:
Demo
~Demo
2.名字空间对象和类静态对象(namespace object,static class object)
在程序开始时(main之前)被创建,在程序结束后(main之后)被销毁。
代码如下(示例):
#include <iostream>
class Demo {
public:
Demo() { std::cout << "Demo" << std::endl; }
~Demo() { std::cout << "~Demo" << std::endl; }
};
namespace WebCore {
Demo d;
}
int main() {
std::cout << "main start" << std::endl;
std::cout << "main end" << std::endl;
}
正确执行后打印:
Demo
main start
main end
~Demo
3.局部静态对象(local static object)
在程序执行到对象被定义的位置创建,在程序结束后销毁(main结束后)。
示例:
#include <iostream>
class Demo {
public:
Demo() { std::cout << "Demo" << std::endl; }
~Demo() { std::cout << "~Demo" << std::endl; }
};
void test() {
static Demo d;//对象定义的位置
}
int main() {
std::cout << "main start" << std::endl;
test();
std::cout << "main end" << std::endl;
}
执行结果:
main start
Demo
main end
~Demo
4.自由存储空间对象(free-store object)
用new创建,用delete销毁。这个没有明确的作用域,主要是看对象创建的位置。
示例:
#include <iostream>
class Demo {
public:
Demo() { std::cout << "Demo" << std::endl; }
~Demo() { std::cout << "~Demo" << std::endl; }
};
void test() {
Demo *demo = new Demo;
delete demo;
}
int main() {
std::cout << "main start" << std::endl;
test();
std::cout << "main end" << std::endl;
}
执行结果:
main start
Demo
~Demo
main end
可以看到,销毁是在test执行结束之后,和static对象的main执行结束销毁有严格区别!
5.临时对象
由特定的子表达式创建,在完整表达式求值完毕后销毁。
示例:
#include <iostream>
class Demo {
public:
Demo() { std::cout << "Demo" << std::endl; }
~Demo() { std::cout << "~Demo" << std::endl; }
};
void test() {
if (true) {
Demo demo;
}
}
int main() {
std::cout << "main start" << std::endl;
test();
std::cout << "main end" << std::endl;
}
执行结果:
main start
Demo
~Demo
main end
其实,再细化的话,在if语句结束就销毁了。
三、很重要
我们看到了出现了很多静态对象,其中局部静态对象值得多说一句。这种静态对象生命周期直到main结束后才回收,而且作用域只在定义它的函数中。也就是说你在函数外面是不能访问它的,如果你定义的是自动内存那么不用操心它的回收问题,如果你是new出来的堆内存,那么你要小心了,如果你把它遗忘了,那它的内存就不会自动回收了,需要借助delete来回收。
当然,程序结束之后那些没有回收的内存其实也会被系统回收掉,只不过最好还是使用new+delete的搭配,不要投机取巧!
总结
1、掌握这三种对象的生命期就可以写出没有bug的代码了,前提是深刻理解。