C++ 的new 运算子和C 的malloc 函数都是为了配置内存,但前者比之后者的优点
是,new 不但配置对象所需的内存空间时,同时会引发构造式的执行。

所谓构造式(constructor),就是对象诞生后第一个执行(并且是自动执行)的函数,它
的函数名称必定要与类别名称相同。

相对于构造式,自然就有个析构式(destructor),也就是在对象行将毁灭但未毁灭之前
一刻,最后执行(并且是自动执行)的函数,它的函数名称必定要与类别名称相同,再
在最前面加一个~ 符号。

#include <iostream>
using namespace std;
class CDemo{
char name[];
public:
CDemo(){
cout<<"class begin !!!"<<endl;
}
CDemo(char * ch)
{
strcpy(name,ch);
cout << "Constructor called for " << name << '/n';
}
~CDemo(){
cout<<"desturctor called for "<<name<<endl;
}
};
void func()
{
CDemo LocalObjectInFunc("LocalObjectInFunc"); // in stack
static CDemo StaticObject("StaticObject"); // local static
CDemo* pHeapObjectInFunc = new CDemo("HeapObjectInFunc"); // in heap
cout << "Inside func" << endl;
}
CDemo GlobalObject("GlobalObject"); // global static
int main()
{
CDemo LocalObjectInMain("LocalObjectInMain"); // in stack
CDemo* pHeapObjectInMain = new CDemo("HeapObjectInMain"); // in heap
cout << "In main, before calling func/n";
func();
cout << "In main, after calling func/n";
system("pause");
}

以上代码的执行结果是:

Constructor called for GlobalObject
Constructor called for LocalObjectInMain
Constructor called for HeapObjectInMain
In main, before calling func
Constructor called for LocalObjectInFunc
Constructor called for StaticObject
Constructor called for HeapObjectInFunc
Inside func
desturctor called for LocalObjectInFunc
In main, after calling func
请按任意键继续. . .

所以可以得到以下几个结论:

  • 对于全域对象(如本例之GlobalObject),程序一开始,其构造式就先被执行
    (比程序进入点更早);程序即将结束前其析构式被执行。MFC 程序就有这
    样一个全域对象,通常以application object 称呼。
  • 对于区域对象,当对象诞生时,其构造式被执行;当程序流程将离开该对象的
    存活范围(以至于对象将毁灭),其析构式被执行。
  • 对于静态(static)对象,当对象诞生时其构造式被执行;当程序将结束时(此
    对象因而将遭致毁灭)其析构式才被执行,但比全域对象的析构式早一步执
    行。
  • 对于以new 方式产生出来的区域对象,当对象诞生时其构造式被执行。析构
    式则在对象被delete 时执行(上例程序未示范)。

四种不同的对象生存方式(in stack、in heap、global、local static)

在C++ 中,有四种方法可以产生一个对象。

第一种方法是在堆栈(stack)之中产生它:

void MyFunc()
   {
           CFoo foo; // 在堆栈(stack)中产生foo 对象
           ...
    }
第二种方法是在堆积(heap)之中产生它:

void MyFunc()
  {
       ...
      CFoo* pFoo = new CFoo(); // 在堆(heap)中产生对象
   }
第三种方法是产生一个全域对象(同时也必然是个静态对象):
        CFoo foo; // 在任何函数范围之外做此动作

第四种方法是产生一个区域静态对象:
   void MyFunc()
  {
       static CFoo foo; // 在函数范围(scope)之内的一个静态对象
       ...
  }

不论任何一种作法,C++ 都会产生一个针对CFoo 构造式的调用动作。前两种情况,C++
在配置内存-- 来自堆栈(stack)或堆积(heap)-- 之后立刻产生一个隐藏的(你的原
代码中看不出来的)构造式调用。第三种情况,由于对象实现于任何「函数活动范围
(function scope)」之外,显然没有地方来安置这样一个构造式调用动作。

是的,第三种情况(静态全域对象)的构造式调用动作必须靠startup 码帮忙。startup 码
是什么?是更早于程序进入点(main 或WinMain)执行起来的码,由C++ 编译器提供,
被联结到你的程序中。startup 码可能做些像函数库初始化、进程信息设立、I/O stream 产
生等等动作,以及对static 对象的初始化动作(也就是调用其构造式)。

当编译器编译你的程序,发现一个静态对象,它会把这个对象加到一个串行之中。更精

确地说则是,编译器不只是加上此静态对象,它还加上一个指针,指向对象之构造式及
其参数(如果有的话)。把控制权交给程序进入点(main 或WinMain)之前,startup 码
会快速在该串行上移动,调用所有登记有案的构造式并使用登记有案的参数,于是就初始化了你的静态对象。

第四种情况(区域静态对象)相当类似C 语言中的静态区域变量,只会有一个实体
(instance)产生,而且在固定的内存上(既不是stack 也不是heap)。它的构造式在
控制权第一次移转到其声明处(也就是在MyFunc 第一次被调用)时被调用。

原文地址:http://blog.csdn.net/j_factory/article/details/3582499

c++对象的生命周期的更多相关文章

  1. [原创]java WEB学习笔记94:Hibernate学习之路---session 的管理,Session 对象的生命周期与本地线程绑定

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  2. [原创]java WEB学习笔记47:Servlet 监听器简介, ServletContext(Application 对象), HttpSession (Session 对象), HttpServletRequest (request 对象) 监听器,利用listener理解 三个对象的生命周期

    本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...

  3. hibernate 持久化对象的生命周期 2.1

    持久化对象的生命周期 瞬态(自由态) 表示对象在内存中存在,在数据库中没有数据相关,比如刚刚new出来的一个对象 持久态 持久态指的是持久化对象处于由Hibernate管理的状态,这种状态下持久化对象 ...

  4. Java 对象的生命周期

    Java对象的生命周期 在Java中,对象的生命周期包含下面几个阶段: 1.      创建阶段(Created) 2.      应用阶段(In Use) 3.      不可见阶段(Invisib ...

  5. 管中窥豹——从对象的生命周期梳理JVM内存结构、GC调优、类加载、AOP编程及性能监控

    如题,本文的宗旨既是透过对象的生命周期,来梳理JVM内存结构及GC相关知识,并辅以AOP及双亲委派机制原理,学习不仅仅是海绵式的吸收学习,还需要自己去分析why,加深对技术的理解和认知,祝大家早日走上 ...

  6. [翻译] 编写高性能 .NET 代码--第二章 GC -- 减少分配率, 最重要的规则,缩短对象的生命周期,减少对象层次的深度,减少对象之间的引用,避免钉住对象(Pinning)

    减少分配率 这个几乎不用解释,减少了内存的使用量,自然就减少GC回收时的压力,同时降低了内存碎片与CPU的使用量.你可以用一些方法来达到这一目的,但它可能会与其它设计相冲突. 你需要在设计对象时仔细检 ...

  7. Hibernate学习(4)- Hibernate对象的生命周期

    1.Hibernate对象的生命周期(瞬时状态.持久化状态.游离状态) 1.瞬时状态(Transient): 使用new操作符初始化的对象就是瞬时状态,没有跟任何数据库数据相关联:2.持久化状态(Pa ...

  8. Unity中巧用协程和游戏对象的生命周期处理游戏重启的问题

    主要用到协程(Coroutines)和游戏对象的生命周期(GameObject Lifecycle)基础知识,巧妙解决了游戏重启的问题. 关于协程,这里有篇文章我觉得写的非常好,理解起来也很容易.推荐 ...

  9. Java虚拟机(三)垃圾标记算法与Java对象的生命周期

    前言 这一节我们来简单的介绍垃圾收集器,并学习垃圾标记的算法:引用计数算法和根搜索算法,为了更好的理解根搜索算法,会在文章的最后介绍Java对象在虚拟机中的生命周期. 1.垃圾收集器概述 垃圾收集器( ...

  10. Javascript - Vue - vue对象的生命周期

    vue对象的生命周期 从vue的创建到销毁会经过一系列的事件,这是vue对象的生命周期. 创建期间的生命周期函数 <div id="box">    <h3 id ...

随机推荐

  1. C语言中的运算和运算符

    一.运算符的优先级和结合性 1,优先级 运算符一览表中,运算符越靠上,优先级越高. 2,结合性 假如用O表示需要两个操作数的双目运算符,那么对于表达式aObOc: 左结合运算符会将表达式解释为  (a ...

  2. MyBatis where标签语句

    当 where 中的条件使用的 if 标签较多时,这样的组合可能会导致错误.当 java 代码按如下方法调用时: @Test public void select_test_where() { Use ...

  3. python_装饰器模式

    装饰器模式定义:动态地给一个对象添加一些额外的职责. 在Python中Decorator mode可以按照像其它编程语言如C++, Java等的样子来实现,但是Python在应用装饰概念方面的能力上远 ...

  4. EF5+MVC4系列(10) mvc的布局页面 _ViewStart.Cshtml

    当客户端请求 /Product/Index的时候, 如果在视图的根目录下有 _ViewStart.Cshtml 就会先执行这个,再去执行 Product文件夹下的Index视图, 如果Product文 ...

  5. List转DataTable(反射) ; 将泛型集合类转换成DataTable ; 将集合类转换成DataTable

    public class ConvertX { #region 将集合类转换成DataTable /// <summary> /// 将集合类转换成DataTable /// </s ...

  6. VS2013 此模板尝试加载组件程序集”NuGet.VisualStudio.interop,Version=1.0.0.0 的解决办法

    此模板尝试加载组件程序集 NuGet.VisualStudio.Interop   分析错误 既然错误信息提示模板尝试加载组件程序集,那说明NuGet.VisualStudio.Interop程序集不 ...

  7. u3d外部资源 打包与加载的问题

    被坑了一下午,调bug,u3d外部加载资源一会可以,一会不行,始终找不到问题,最后快下班的时候,重新试了一下,原来是资源打包之前的文件名,和之后的加载资源名必须一样 [MenuItem("C ...

  8. CSDN极客头条使用指南

    CSDN极客头条使用指南 今天给大家介绍一下CSDN博客最新推出的这个栏目--CSDN极客头条. 极客头条是什么 极客头条大家分享优质IT资源的聚集地. 大家不仅能够分享CSDN的文章,更能够将其它社 ...

  9. 简单理解IoC与DI

    为了理解Spring的IoC与DI从网上查了很多资料,作为初学者,下面的描述应该是最详细,最易理解的方式了. 首先想说说IoC(Inversion of Control,控制倒转).这是spring的 ...

  10. p12证书转keystore签名

    java https://my.oschina.net/u/555639/blog/524821   AIR p12转keystore证书签名apk 2014年01月03日 ⁄ 移动探索 ⁄ 评论数 ...