Object lifetime

  • Temporary object lifetime
  • Storage reuse
  • Access outside of lifetime

    Every object has a lifetime, which is a runtime property: for any object, there is a moment during the execution of a program when its lifetime begins, and there is a moment when it ends.

    简单而言,对象生命周期的从初始化开始,到析构函数调用为止。
  • For objects of class or aggregate types that are initialized by anything other than the trivial default constructor, lifetime begins when initialization ends.
  • For objects of class types whose destructor is not trivial, lifetime ends when the execution of the destructor begins.
  • For all other objects (class objects initialized by a trivial default constructor, non-class objects, array objects, etc.), lifetime begins when the properly-aligned storage for the object is allocated and ends when the storage is deallocated or reused by another object.

Lifetime of an object is equal to or is nested within the lifetime of its storage, see storage duration.

Lifetime of a reference is exactly its storage duration (which makes dangling references possible).

Lifetimes of member objects and base subobjects begin and end following class initialization order.

Temporary object lifetime

Temporary objects are created in various situations: binding a reference to a prvalue, returning a prvalue from a function, cast to a prvalue, throwing an exception, entering an exception handler, and in some initializations. In every case, all temporary objects are destroyed as the last step in evaluating the full-expression that (lexically) contains the point where they were created.

If multiple temporary objects were created, they are destroyed in the order opposite to the order of creation. This is true even if that evaluation ends in throwing an exception.

There are two exceptions from that:

  • The lifetime of a temporary object may be extended by binding to a const lvalue reference or to an rvalue reference (since C++11), see reference initialization for details.
  • The lifetime of a temporary object created when evaluating the default arguments of a default constructor used to initialize an element of an array ends before the next element of the array begins initialization.(since C++11)

Storage reuse

###Access outside of lifetime
If an object was destroyed (e.g. by explicit destructor call), but the storage was not deallocated, the following uses of the glvalue expression that identifies that object are undefined:
1. Lvalue to rvalue conversion (e.g. function call to a function that takes a value).
2. Access to a non-static data member or a call to a non-static member function.
3. Binding to reference to a virtual base class subobject.
4. dynamic_cast or typeid expressions.

If an object is recreated at the same memory location (e.g. by placement new), the glvalue becomes valid once again, if all of the following is true:

  1. The storage occupied by the new object exactly overlays the storage occupied by the old object.
  2. The new object has the same type as the old object, ignoring top-level cv-qualifiers.
  3. The original object's type was not const-qualified.
  4. The original object was not a class with const or reference non-static data members.
  5. Both the original and the new objects are the most-derived objects of their type.

The above rules apply to pointers as well (binding a reference to virtual base is replaced by implicit conversion to a pointer to virtual base), with two additional rules:

  1. static_cast of a pointer to storage without an object is only allowed when casting to (possibly cv-qualified) void*.
  2. Pointers to storage without an object that were cast to possibly cv-qualified void* can only be static_cast to pointers to possibly cv-qualified char or pointer to possibly cv-qualified unsigned char.

During construction and destruction, other restrictions apply, see virtual function calls during construction and destruction.

Virtual function call during construction and destruction

When a virtual function is called directly or indirectly from a constructor or from a destructor (including during the construction or destruction of the class’s non-static data members, e.g. in a member initializer list), and the object to which the call applies is the object under construction or destruction, the function called is the final overrider in the constructor’s or destructor’s class and not one overriding it in a more-derived class. In other words, during construction or destruction, the more-derived classes do not exist.

When constructing a complex class with multiple branches, within a constructor that belongs to one branch, polymorphism is restricted to that class and its bases: if it obtains a pointer or reference to a base subobject outside this subhierarchy, and attempts to invoke a virtual function call (e.g. using explicit member access), the behavior is undefined:

struct V {
virtual void f();
virtual void g();
}; struct A : virtual V {
virtual void f(); // A::f is the final overrider of V::f in A
};
struct B : virtual V {
virtual void g(); // B::g is the final overrider of V::g in B
B(V*, A*);
};
struct D : A, B {
virtual void f(); // D::f is the final overrider of V::f in D
virtual void g(); // D::g is the final overrider of V::g in D // note: A is initialized before B
D() : B((A*)this, this)
{
}
}; // the constructor of B, called from the constructor of D
B::B(V* v, A* a)
{
f(); // virtual call to V::f (although D has the final overrider, D doesn't exist)
g(); // virtual call to B::g, which is the final overrider in B v->g(); // v's type V is base of B, virtual call calls B::g as before a->f(); // a’s type A is not a base of B. it belongs to a different branch of the
// hierarchy. Attempting a virtual call through that branch causes
// undefined behavior even though A was already fully constructed in this
// case (it was constructed before B since it appears before B in the list
// of the bases of D). In practice, the virtual call to A::f will be
// attempted using B's virtual member function table, since that's what
// is active during B's construction)
}

Object lifetime的更多相关文章

  1. C++ 自由存储区是否等价于堆?

    "free store" VS "heap" 当我问你C++的内存布局时,你大概会回答: "在C++中,内存区分为5个区,分别是堆.栈.自由存储区.全 ...

  2. free store VS heap(自由存储区VS堆)

    1. free store VS heap free store (自由存储区)和 heap (堆),在C/C++中经常会遇到.他们是否有区别呢? 偶最早发现这两个概念性问题是在<Excepti ...

  3. C++的最佳特性(译)

    最近看到了很多优秀的文章,包括<Why mobile web apps are slow>,实在忍不住翻译出来跟大家分享.这篇文章通过大量的实验和参考文献向我们说明移动应用开发所遇到的问题 ...

  4. winston日志管理1

    Usage There are two different ways to use winston: directly via the default logger, or by instantiat ...

  5. AutoReleasePool 和 ARC 以及Garbage Collection

    AutoReleasePool autoreleasepool并不是总是被auto 创建,然后自动维护应用创建的对象. 自动创建的情况如下: 1. 使用NSThread的detachNewThread ...

  6. Finalization

    1.what is the main disadvantage of garbage collection? Typically, garbage collection has certain dis ...

  7. Weak Event Patterns

    https://msdn.microsoft.com/en-US/library/aa970850(v=vs.100).aspx In applications, it is possible tha ...

  8. Using Sessions and Session Persistence---reference

    Using Sessions and Session Persistence The following sections describe how to set up and use session ...

  9. .net程序员必须知道的知识

    A while back, I posted a list of ASP.NET Interview Questions. Conventional wisdom was split, with ab ...

随机推荐

  1. Decorators and Wrappers in Python

    python代码一贯以优雅,简洁著称,而有时侯反而会让人难以理解,比如说wrapper(或者说decorator),这种方式提高了代码的可重用性,使用起来更简洁方便. 举个例子,比如WebApp常用的 ...

  2. Linux 查看支持的语言,日期,时间,计算器

    1.查看系统目前支持的语言 echo %LANG 2.查看日历 cal 3.查看日期时间 date 4.计算器 bc

  3. Changing the Auto-Logout Timeout in SSH

    SSH: We can set a timeout interval for ssh client who are idle or in inactive state. As soon as the ...

  4. Android TextWatcher应用实例

    (1)使用TextWathcer限制输入字符个数布局中EditText在android布局中经常用到,对EditText中输入的内容也经常需要进行限制,我们可以通过TextWatcher去观察输入框中 ...

  5. 基于视觉信息的网页分块算法(VIPS) - yysdsyl的专栏 - 博客频道 - CSDN.NET

    基于视觉信息的网页分块算法(VIPS) - yysdsyl的专栏 - 博客频道 - CSDN.NET 于视觉信息的网页分块算法(VIPS) 2012-07-29 15:22 1233人阅读 评论(1) ...

  6. PHP批量下载方法

      PHP批量下载方法 界面: $.get(“< ?php echo url::base(true);?>inventory/report/buildCsv”, //后台路径 {‘para ...

  7. Linux操作系统定时任务系统Cron入门、PHP计划任务以及rpc示例

    一.简单介绍 1.cron是一个linux下的定时执行工具,可以在无需人工干预的情况下运行作业.由于Cron 是Linux的内置服务,但它不自动起来,可以用以下的方法启动.关闭这个服务: servic ...

  8. poj 1815 Friendship (最小割+拆点+枚举)

    题意: 就在一个给定的无向图中至少应该去掉几个顶点才干使得s和t不联通. 算法: 假设s和t直接相连输出no answer. 把每一个点拆成两个点v和v'',这两个点之间连一条权值为1的边(残余容量) ...

  9. [C# 基础知识系列]专题六:泛型基础篇——为什么引入泛型

    引言: 前面专题主要介绍了C#1中的2个核心特性——委托和事件,然而在C# 2.0中又引入一个很重要的特性,它就是泛型,大家在平常的操作中肯定会经常碰到并使用它,如果你对于它的一些相关特性还不是很了解 ...

  10. 转载ajax

    写在前面的话: 用了很久的Asp.Net Ajax,也看了段时间的jquery中ajax的应用,但到头来,居然想不起xmlHttpRequest的该如何使用了. 以前记的也不怎么清楚,这次就重新完整的 ...