提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
我们写C++就不可避免需要用到变量,用到变量就要知道生命周期原则,要不然写的代码自带bug,崩盘只是迟早的事。
生命期顾名思义就是出生到死亡的这个时间。放到C++的对象上就是从对象被创建开始到对象被回收结束这么一个过程。
前面已经说了生命周期是相对于对象来说的,要讲解生命期必须围绕着对象的类型来说,不同类型的对象生命期是完全不一样的。
又称自动对象
(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
在程序开始时
(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
在程序执行到对象被定义的位置创建
,在程序结束后销毁
(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
用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
执行结束销毁有严格区别!
由特定的子表达式创建
,在完整表达式求值完毕后销毁
。
示例:
#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的代码了,前提是深刻理解
。