存储持续时间与寿命

时间:2014-01-27 21:34:32

标签: c++

有人可以向我解释storage durationlifetime对象之间的区别吗?我认为他们表示同样的事情。我找到了一个定义:

  

对象的生命周期等于或嵌套在其存储的生命周期内。

所以根据这个,我看不到有一点差别。另外,如果有人用低级别的术语向我解释这些概念,我将非常感激。我宁愿考虑memoryadressesdata而不是高级别的东西。感谢。

Link to the definition above

5 个答案:

答案 0 :(得分:13)

存储时间是以下四个字之一:

  • 自动
  • 静态
  • 动态
  • 线程(本地)

那就是它。它告诉您什么时候适用于创建和销毁对象的规则。

生命周期是程序运行时的一部分,在此期间对象可用。一般来说,这是从构造到破坏,但是对于普通类型(没有构造函数或析构函数的那些类型),从分配内存到内存被释放或用于另一个对象时,它就是#34;。

所以这两者是相关的,但它们并不完全相同。具有不同存储持续时间的两个对象可以具有相关且几乎相同的生命周期(例如,自动unique_ptr及其管理的动态对象),并且具有相同存储持续时间的两个对象可以具有完全不同的生存期(尤其是两个动态对象) )。

答案 1 :(得分:4)

你走进麦当劳,并看到一个菜单。菜单上有许多不同的食物,包括巨无霸,带奶酪的四分之一磅蛋糕,热苹果派以及令人厌恶的Filet-O-Fish。

你走到柜台并点了一台巨无霸。你会看到一个3层面包,2个“全牛肉”馅饼和一些特殊的酱汁,都装在一张纸上。

你身后的人命令同样的事情,并给他们自己的汉堡。你们都坐下来开始吃饭。你吃得很快,但你的邻居几乎没有接触到他。

排在第三位的苹果派人员,给他们一些完全不同的东西。一个小半圆形的糕点,里面装满了类似苹果的东西。

在这个类比中,菜单上的打印是存储持续时间,汉堡的类型本身类似于对象的生命周期。选择了两种不同的存储持续时间;巨无霸和苹果派。结果产生了三个物体:两个汉堡和一个糕点。其中两个具有相同的一般化妆,即使它们是两个不同的汉堡,但第三个是不同的。两个存储持续时间,三个对象。


你的引言:

  

对象的生命周期等于或嵌套在生命周期内   它的存储。

“生命周期”或“存储持续时间”不是定义,而只是将两者联系起来。它告诉你,给定X的“存储持续时间”你可以期望Y的生命周期。

从这个意义上说,这两个术语实际上是同一枚硬币的两面。特定的存储持续时间会产生特定的寿命。

这在(C ++ 03)标准中详细说明:

3.8对象生命周期

  

1 /对象的生命周期是对象的运行时属性。该   类型T的对象的生命周期从以下开始: - 使用适当的存储   获得类型T的对齐和大小,并且 - 如果T是类类型   使用非平凡的构造函数(12.1),构造函数调用具有   完成。类型T的对象的生命周期在以下情况下结束: - 如果T是a   具有非平凡析构函数(12.4)的类类型,析构函数调用   开始,或 - 对象占用的存储被重用或   释放。

3.7存储持续时间

  

1 /存储持续时间是定义最小值的对象的属性   包含对象的存储的潜在生命周期。存储   持续时间由用于创建对象的构造确定   是以下之一: - 静态存储持续时间 - 自动存储   持续时间 - 动态存储持续时间

答案 2 :(得分:2)

简单来说,存储持续时间是指的时间段 保证对象下面的内存可用; 生命周期是你可以用它作为对象的时期 指定的类型。差异最明显的例子 是你打电话给std::vector<>::reserve;这分配了 内存为相应数量的对象,但它们没有 在你调用一些构造的函数之前一直可用 他们。

在其他情况下:考虑了简单构造的对象 有一个等于他们的存储持续时间的寿命,但这 实际上并不是真的;直到对象已初始化, 你可以用它做的事情有限(没有 特别是左值转换价值。在另一端, 具有非平凡构造函数的对象的生命周期 析构函数被认为是从你返回时开始的 构造函数,并在您进入析构函数时结束,但在那里 你可以做很多事情 构造函数和析构函数正在运行。当然,只要 因为你所做的就是复制内存的地址,这是唯一的 其中包括存储时间。

答案 3 :(得分:1)

  

我宁愿考虑memoryadressesdata而不是高级别的东西。

存储数据的位置取决于

指出的几种可能性
    函数调用堆栈中的
  • 自动 =&gt; (另见RAII
  • (正确初始化的)全局数据部分
  • static =&gt; (另见RAII
  • 堆上的
  • 动态 =&gt; (来自new()malloc()来电的分配)
  • 线程(本地) =&gt; 关于特定线程的私有数据(注意:尝试在线程之间直接共享线程私有数据,导致异常。)< / LI>

您的班级实例的终身,以及存储持续时间 - 由范围确定,它们是共享的内。
当然,对于线程,您可能同时共享范围,并应谨慎遵守 通常检查不需要的副本,即rvalue引用。

一起使用的首选范例是RAII非常好支持最新 {的内存管理功能{3}} 即可。
后者封装了阻塞作用域{ ... }的管理,以及整个'virtual'作用域,它管理封装类实例的生命周期,甚至是动态分配的对象。

答案 4 :(得分:0)

这是我目前所理解的(并且认为是对的):

生命周期与存储持续时间不同的唯一情况是使用动态对象时。例如,两个静态对象或两个自动对象具有相同的生命周期。如果我们在函数范围的末尾结束动态对象的生命周期,我们可以拥有自动对象和动态对象(不同的存储持续时间),并且这两者具有相同的生命周期。这是因为我们可以随时结束动态对象的生命周期,并获得与具有不同存储持续时间的其他对象相同的生命周期。此外,通过释放第一个对象占用的内存,我们可以拥有两个不同的动态对象,并为第一个对象提供比第二个对象更短的生命周期。

在一天结束时,这些定义成立:

对象的

Lifetime在调用构造函数时启动,并持续到调用析构函数为止。 (或从它的创建到它的删除)

Storage duration用简单的话来“保证”将要创建的对象可用(它可以使用为其分配的内存),直到它指定的时刻。例如,如果它是static对象,它将持续到程序终止,automatic当函数结束时,dynamic当用户调用delete时。

如果我在某处错了,请纠正我。