C++ Primer中关于函数调用的一个问题
面向对象编程的一个重要概念是对象的生命周期。不管是int这种原始类型值,还是string这种类的类型,都可以认为是对象,有自己的生命周期。函数临时变量的生命周期从定义它的语句开始,到作用域结束为止,可以简单认为是套住它的大括号之间。对象生命周期结束之前会进行析构,对于int这种原始类型其析构的逻辑是不作任何操作,对于string这种类对象调用其析构函数。函数的临时变量都存在栈上,栈是系统给每个线程分配的一整块内存空间,这块内存在线程结束前是不会回收的。函数内的每个变量都临时占有一小块,这也是它们称作临时变量的原因。函数返回后,这些变量(对象)的生命周期结束,这些内存空间会在下次函数调用中继续使用,由其它临时变量再临时占有。这就像坐公交车有很多座位,乘客上车坐到座位上,下车之后这个座位其它乘客还可以做。如果某个乘客一边坐车一边吃零食,下车之后垃圾没带走留在座位上,其它乘客想要坐就应该先清理这些垃圾。对应到你这段程序中,进入到函数fun,栈上的一块空间由a临时占用,a是int时,写入了12345,返回时由于原始变量析构逻辑是什么也不做,这块空间内的值依然是12345,你在外面访问它还能得到12345。如果你调用其它函数后再访问这个值就很可能不一样了。而a是string的时候调用了string的析构方法,已经清空了其内存(严格来说还有堆的问题,不影响),所以返回后立即访问是空。同理中间有其它函数调用再访问情况是不一样的。总的来说,出了作用域的临时变量中内容是未定义的,不应该继续使用。而声明原始变量时也一定要先初始化,因为其中可能包含之前其它函数调用是临时变量的垃圾数据。声明类对象的时候,会自动调用类的构造函数以完成初始化的任务,因此构造函数有应该将所有类成员初始化,保证它们都在可用的状态。
■网友
第一段程序不是指针a依然可用 而且a指向的内存很侥幸的没被覆盖 你可以在第一段程序里试试多输出几次 *a 按这个思路 第二段程序也应该可以输出hello才对但是很不幸的是 string不是基础数据类型 它是个class 在生命周期里有构造和析构的过程,在函数返回前它被无情的析构了 它指向的内存是啥 要看编译器和操作系统的心情
■网友
你不能保证一段已经被释放的内存里究竟有什么。
■网友
返回局部对象的引用是错误的,返回局部对象的指针也是错误的。为什么是错误的,因为会引发未定义(不确定)的行为。
■网友
建议学习一下程序的内存布局,包括栈,函数怎么传参数的,返回值怎么传递,什么是堆,堆怎么分配。再看一下C++这些语义,包括类类型的构造与析构,与基本类型的差别。
推荐阅读
- 过节■江苏省委省政府办公厅下发关于做好2021年元旦春节期间有关工作的通知
- |徐州市出台《关于优化创新创业生态系统 提升区域科技创新活力的实施意见》及实施细则
- 雨下|全球关于禁售燃油车只是理论上可行吗
- 关于用phpfsocket 写Post, 模拟http 报文怎样写入要传输的处理数据
- 智叔|很多家长还在整箱买:谈谈关于牛奶的17个真相警惕这些列入黑名单的“假牛奶”
- 非计算机专业想要利用课余时间深入自学C++,想要找到比较体面的工作大概需要啥水平
- 关于微信小程序的思考:运营者该何去何从
- 关于人工智能虚拟人的一些问题
- 知乎上关于人生经验的介绍是否可能对青少年造成潜在危害
- Java工程师和C++工程师在工作上有啥区别哪个更适合自身发展
