zoukankan      html  css  js  c++  java
  • Symbian点滴3对象的创建和释放以及对象的二阶段构造

    虽然Symbian使用的是c++语言,但是由于手机系统的硬件限制,与c++语言差别还是比较大,Symbian定义了一套自己的东西。

    主要是对象的二阶段构造,清除栈。

    1.堆和栈。

    堆资源比较大,可以动态分配内存空间,在堆上创建的对象,使用以后都要显式的清除。

    一般使用new来在进程的默认堆上分配一个空间。如果内存不足就会报一个异常。一个小列子

    //CMyClass类定义

    class CMyClass : public CBase

    {

    public:

    CMyClass();//构造函数

    ~CmyClass();//析构函数

    void Function();//普通函数

    }

    //在堆上创建cmyclass类的对象

    CMyClass* ptr = new CMyClass;

    if(ptr != null)

    {

     ptr->Function();//调用方法

    delete ptr;//释放指针指向的内存空间

    ptr =null;//设置指针为null

    在上面代码中,创建类的对象的时候有可能因为内存不足而报错,所以要先检查ptr是不是null,然后才可以调用function 方法。

    Symbian中提供了一个ELeave宏,并且重载了new操作符。使用new(ELevae)创建对象的时候,如果内存分配失败,创建的函数将不再执行后面的代码,而是立即退出。所以使用new(ELeave)创建对象,可以省略检查对象是不是为null的步骤

    CMyClass* ptr = new CMyClass;

     ptr->Function();//调用方法

    delete ptr;//释放指针指向的内存空间

    ptr =null;//设置指针为null

    -----------------------------------------------------------

    在说说栈(stack)。栈上的对象也称为自动变量,因为他不用手工去创建和释放空间。只是栈的空间很小,Symbian系统的栈只有8kb。所以只用来创建简单的字段或者对象。

    2.清除栈(CleanUp Stack)

      清除栈的作用就是保证在异常发生的时候释放堆上的对象。

    还使用上面的列子,看一个函数方法

    void SomeClass::FunctionL()

    {

      TInt integer;

      CMyClass* object = new(ELeave)CMyClass;

    object->Function();

    delete object;

    object =null;

    }

     CMyClass* object = new(ELeave)CMyClass;如果这个步骤没有成功,异常的话,integer和object都会释放内存资源的,不会发生内存泄漏的问题。

    但是如果生成类的步骤成功,但是在执行Function()的时候错误,发生异常了。这个Function()方法会立刻返回,integer和object会被自动释放,但是object指向的CMyClass对象失去了唯一可以访问他的指针,这个对象的空间成为系统的内存漏洞。

      避免这个情况的方法就是使用清除栈。CleanupStack。原来就是将可能异常退出的对象,在他执行之前将对象的指针压入这个清除栈。使用CleanupStack::PushL()函数。

    void SomeClass::FunctionL()

    {

      TInt integer;

      CMyClass* object = new(ELeave)CMyClass;

    //后面的代码可能有一场,会丢失object,造成object执行的cmyclass不可访问,所以先把他压入栈

    CleanupStack:PushL(object);

    object->Function();

    //程序没有异常,将object对象弹出清除栈

    Cleanup::Pop();//弹出栈但是没有清除资源

    delete object;

    object =null;

    }

    (CleanupStack主要3个方法PushL,Pop,PopAndDestroy//弹出并清除了资源)

    3类对象的两阶段构造

    Symbian提供的两阶段构造方法,配合清除栈,保证异常退出时候系统不会产生内存泄漏。

    3。1原理。

    c++中new方法完成两个功能:一个是在堆上申请空间,然后就是执行构造函数完成对对象的构造。

    所以在Symbian中的重要规则就是:

    第一阶段使用new(Eleave)申请对象空间。并且调用该类的默认构造函数,而且这个构造函数必须是没有异常发生的

    第二阶段讲对象压入清除栈,只有调用类的ConstructL()方法,进行一些可能发生异常的操作

    所以一个标准的C类应这样定义:

    class CClass1 : CBase

    {

    public:

    CClass1();

    ~CClass1();

    void ConstructL();//新增这个函数,里面执行可能有异常发生的操作

    private:

    CClass1* member;

    }

    CClass1::CClass1()//构造函数执行肯定不会有异常发生的操作

    {

    }

    CClass1::ConstrunctL()//执行可能会有异常发生的操作

    {

       member = new(ELeave)CClass1;

    }

    CClass1::~CClass1()

    {

      delete member;

    }

    这样,调用这个类的时候,可以这样写。就是两个阶段的构造

    CClass1* obj = new(ELeve)CClass1;

    CleanupStack::PushL(obj);

    obj->ConstructL();

    ...

    CleanupStack::PopAndDestroy();

    -----------------------------------------------------------------------

    但是这样写有点麻烦。就是生成类的对象的时候,每次都要写4行代码。所以要进一步封装

    Symbian的规范是使用静态的newL()和newLC()。然后吧构造函数报刊constructL都变成私有的函数。这样写:

    class CClass1 : CBase

    {

    public:

    static CClass1* newL();

    static CClass1* newLC();

    ~CClass1();

    private:

    CClass1();

    void ConstructL();//新增这个函数,里面执行可能有异常发生的操作

    private:

    CClass1* member;

    }

    CClass1* CClass1::NewLC()//没有执行出栈操作。所以调用newLC以后,要调用一下出栈函数

    {

    CClass1* self = new(ELeave)CClass1;

    CleanupStack::PushL();

    self->ConstructL();

    return self;

    }

    CClass* CClass::NewL()//newl方法调用newLC方法,包含了出栈操作。

    {

     CClass1* self = CClass1::NewLC();

     CleanupStack::Pop();

     return self;

    }

    本文使用Blog_Backup未注册版本导出,请到soft.pt42.com注册。

  • 相关阅读:
    tensorflow入门(三)
    tensorflow入门(二)
    setTimeout
    PreResultListener
    sql 删除重复记录
    oracle dual表用途及结构详解
    oracle中的dual表
    Dubbo远程调用服务框架原理与示例
    struts2和spring的两种整合方式
    Timer和TimerTask详解
  • 原文地址:https://www.cnblogs.com/zjypp/p/2319399.html
Copyright © 2011-2022 走看看