• 第27课二阶构造模式(下)


    二阶构造
    工程开发中的构造过程可分为
    -资源无关的初始化操作
      不可能出现异常情况的操作
    - 需要使用系统资源的操作
      可能出现异常情况,如:内存申请,访问文件

    二阶构造示例一
    class TwoPhaseCons{
    private:
      TwoPhaseCons(){ //第一阶段构造函数,就是用C++中的构造函数。

      }
      bool construct(){ //第二阶段构造函数,一个普通的成员函数。
        .......
        return true;
      }
    public:
      static TwoPhaseCons* NewInstance(); //对象创建函数

    }

     注意:第一阶段的构造函数放在了private下面,就意味着它不能被外界调用了。即不能通过类名直接来定义一个对象了。

    二阶构造示例二
    TwoPhaseCons* TwoPhaseCons:: NewInstance() {
      TwoPhaseCons* ret = new TwoPhaseCons(); //在堆空间中创建一个对象,在创建对象的时候,构造函数肯定被调用。即第一阶段

      //若第二阶段构造失败,返回NULL
      if( !(ret && ret->construct())){
        delete ret;
        ret = NULL;
      }

      return ret;
    }

    二阶构造函数初探:

    #include <stdio.h>
    
    class TwoPhaseCons 
    {
    private:
        TwoPhaseCons() // 第一阶段构造函数
        {   
        }
        bool construct() // 第二阶段构造函数
        { 
            return true; 
        }
    public:
        static TwoPhaseCons* NewInstance(); // 对象创建函数
    };
    
    TwoPhaseCons* TwoPhaseCons::NewInstance() 
    {
        TwoPhaseCons* ret = new TwoPhaseCons();
    
        // 若第二阶段构造失败,返回 NULL    
        if( !(ret && ret->construct()) ) 
        {
            delete ret;
            ret = NULL;
        }
            
        return ret;
    }
    
    
    int main()
    {
       //TwoPhaseCons obj;  //编译会出错,因为构造函数被定义成私有的,不能在类的外部直接调用(main 又不是类的成员函数) 
    TwoPhaseCons
    * obj = TwoPhaseCons::NewInstance(); printf("obj = %p ", obj); delete obj; return 0; }

     二阶构造的意义在于:要么得到一个合法可用的对象,要么返回一个空。二阶构造用于杜绝半成品的对象。

    将数组类进行改写:

    IntArray.h

    #ifndef _INTARRAY_H_
    #define _INTARRAY_H_
    
    class IntArray
    {
    private:
        int m_length;
        int* m_pointer;
        
        IntArray(int len);
        bool construct();
    public:
        static IntArray* NewInstance(int length); 
        int length();
        bool get(int index, int& value);
        bool set(int index ,int value);
        ~IntArray();
    };
    
    #endif

    IntArray.cpp

    #include "IntArray.h"
    
    IntArray::IntArray(int len)
    {
        m_length = len;
    }
    
    bool IntArray::construct()
    {
        bool ret = true;
        
        m_pointer = new int[m_length];
        
        if( m_pointer )
        {
            for(int i=0; i<m_length; i++)
            {
                m_pointer[i] = 0;
            }
        }
        else
        {
            ret = false;
        }
        
        return ret;
    }
    
    IntArray* IntArray::NewInstance(int length) 
    {
        IntArray* ret = new IntArray(length);
        
        if( !(ret && ret->construct()) ) 
        {
            delete ret;
            ret = 0;
        }
            
        return ret;
    }
    
    int IntArray::length()
    {
        return m_length;
    }
    
    bool IntArray::get(int index, int& value)
    {
        bool ret = (0 <= index) && (index < length());
        
        if( ret )
        {
            value = m_pointer[index];
        }
        
        return ret;
    }
    
    bool IntArray::set(int index, int value)
    {
        bool ret = (0 <= index) && (index < length());
        
        if( ret )
        {
            m_pointer[index] = value;
        }
        
        return ret;
    }
    
    IntArray::~IntArray()
    {
        delete[]m_pointer;
    }

    main.cpp

    #include <stdio.h>
    #include "IntArray.h"
    
    int main()
    {
        IntArray* a = IntArray::NewInstance(5);    
        
        printf("a.length = %d
    ", a->length());
        
        a->set(0, 1);
        
        for(int i=0; i<a->length(); i++)
        {
            int v = 0;
            
            a->get(i, v);
            
            printf("a[%d] = %d
    ", i, v);
        }
        
        delete a;
        
        return 0;
    }

    小结:
    构造函数只能决定对象的初始化状态
    构造函数中初始化操作的失败不影响对象的诞生
    初始化不完全的办成品对象是Bug的重要来源
    二阶构造人为的将初始化过程分为两部分
    二阶构造能够确保创建的对象都是完整初始化的

  • 相关阅读:
    Java 学习使用常见的开源连接池
    Java 数据库操作
    Java 集合的简单理解
    windows中在vs code终端使用bash
    敏捷开发、DevOps相关书籍——书单
    使用Dockerfile来构建镜像
    Redis集群搭建
    使用redis限制ip访问次数
    NFS服务器搭建
    ssh 中 远程文件传输
  • 原文地址:https://www.cnblogs.com/-glb/p/11876695.html
Copyright © 2020-2023  润新知