c++ - 析构函数何时此对象超出范围
问题描述
class Entity {
//attributes
public:
float X, Y;
Entity() {
X = 0;
Y = 0;
cout << "Created Entity!" << endl;
}
~Entity() {
cout << "Entity Destroyed!" << endl;
}
void Print() {
cout << X << ", " << Y << endl;
}
};
void func() {
Entity e;
e.Print();
}
int main()
{
func();
cout << "b";
}
所以我有点难以理解这里到底发生了什么,我不明白 e 何时以及如何超出范围。func 创建 e 然后调用方法函数,但是只有当我在 main 中调用 func 时才执行所有这些,对吗?因此,只有当我在 main e 中调用 func 并调用该方法时,它究竟是如何超出范围的?
就像有人可以试着解释一下,就像我是一个 5 岁的孩子一样吗?仅当在 main 中调用 func 时才创建实体,对吗?e 什么时候可能超出范围?
解决方案
我不明白 e 何时以及如何超出范围
的范围是e
从其声明到其封闭块范围结束的所有内容:
void func()
{ // start of block scope
Entity e; // e created in the enclosing block scope here
e.Print();
} // end of block scope, e (and any other automatic locals) destroyed
但是只有当我在 main 中调用 func 时才会执行所有这些操作吗?
现在你混淆了两件事:
- 范围是源代码中
e
有效标识符的部分(并且指的是同一个对象,以防您在其他代码中有其他同名的变量)。这是静态的,在编译时都是已知的。 - 控制流是什么时候
func
实际执行的,进入其块作用域,执行函数体中的语句,最后退出块作用域(同时销毁任何自动本地对象)。这发生在运行时,并且是动态的(从某种意义上说,它可能取决于条件逻辑或输入)。
因此,只有当我在 main e 中调用 func 并调用该方法时,它究竟是如何超出范围的?
它具有自动作用域,因此它的作用域在封闭块出现时结束。对于e
,那是func
执行完成且控制返回到 之前的时间main
。
... e 什么时候可能超出范围?
在调用 to 之后尝试引用e
in 。它编译吗?main
func
不,因为e
不是此范围内的标识符。
有什么选择?每个大型程序都会累积在全局命名空间中使用过的每个变量名。它会很快变得难以管理,事实上这正是我们使用局部变量而不是全局变量的原因。
请注意,我们可以通过返回一些东西来将作用域与生命周期分开。如果我们选择具有动态生命周期的东西:
std::unique_ptr<Entity> foo()
{ // block begins
std::unique_ptr<Entity> e; // e scope begins
e.reset( new Entity ); // *e lifetime begins
e->Print();
return std::move(e); // *e moves to return value
} // e destroyed
int main()
{
auto f = foo(); // *e is now called *f
f->Print();
} // f destroyed and deletes *f
- 可以看到有一个匿名对象(
new
由*e
*f
e
具有与以前相同的(块)范围e
具有相同的(自动)生命周期,因此在超出范围时会被销毁- 原来已知的对象
*e
被移交给f
并保持存在。它仍然没有可以绑定到范围的自己的标识符。 f
还具有块范围和自动生命周期*f
(以前称为 的动态对象*e
)被销毁f
只是因为我们没有将它移到其他地方。
推荐阅读
- python - 在 fasta 文件中更改反向序列的方向不起作用
- amazon-web-services - AWS 中文本处理的最佳方法是什么?
- ruby-on-rails - Ruby Rails Excel 格式数组操作
- angular - 将所有工件移至 S3 根目录
- tfs - 构建定义如何在构建过程中取消搁置给定的搁置集
- http - Postman 如何通过 HTTP 发送文件?
- java - ModelMapper 和 LocalDate - Spring Boot
- api - 将搜索框添加到多边形绘图谷歌地图
- python - 如何让自适应 dask 工作人员在启动时运行一些代码?
- c# - DisplayAlert 在 WPF 中没有响应 - Xamarin Forms