• 二阶构造模式


    模式:方法。设计模式,就是设计方法。前人证明了的行之有效的方法。

    构造函数:

    1.关于构造函数

     -类的构造函数用于对象的初始化。

     -构造函数与类同名并且没有返回值。

     -构造函数在对象定义时自动被调用。

    问题:

    1.如何判断构造函数的执行结果?

    2.在构造函数中执行return语句会发生什么?

    3.构造函数执行结束是否意味对象构造成功?

    编程实验:异常的构造函数.cpp

     1 #include <stdio.h>
     2 
     3 class Test
     4 {
     5     int mi;
     6     int mj;
     7     bool mStatus;
     8 public:
     9     Test(int i, int j) : mStatus(false)
    10     {
    11         mi = i;
    12         
    13         return;
    14         
    15         mj = j;
    16         
    17         mStatus = true;
    18     }
    19     int getI()
    20     {
    21         return mi;
    22     }
    23     int getJ()
    24     {
    25         return mj;
    26     }
    27     int status()
    28     {
    29         return mStatus;
    30     }
    31 };
    32 
    33 int main()
    34 {  
    35     Test t1(1, 2);
    36     
    37     if( t1.status() )
    38     {
    39         printf("t1.mi = %d
    ", t1.getI());
    40         printf("t1.mj = %d
    ", t1.getJ());
    41     
    42     }
    43     
    44     return 0;
    45 }

    你需要知道的真相:

    -构造函数

    1.只提供自动初始化变量的机会;

    2.不能保证初始化逻辑一定成功;

    3.执行return 语句后构造函数立即结束。

    构造函数能决定的只是对象的初始状态,而不是对象的诞生。

    半成品对象:

    -初始化操作不能按照预期完成而得到的对象;

    -半成品对象是合法的C++对象,也是BUG的重要来源。

    半成品对象的危害

    IntArray.cpp

     1 #include "IntArray.h"
     2 
     3 IntArray::IntArray(int len)
     4 {
     5     m_length = len;
     6 }
     7 
     8 bool IntArray::construct()
     9 {
    10     bool ret = true;
    11     
    12     m_pointer = new int[m_length];
    13     
    14     if( m_pointer )
    15     {
    16         for(int i=0; i<m_length; i++)
    17         {
    18             m_pointer[i] = 0;
    19         }
    20     }
    21     else
    22     {
    23         ret = false;
    24     }
    25     
    26     return ret;
    27 }
    28 
    29 IntArray* IntArray::NewInstance(int length) 
    30 {
    31     IntArray* ret = new IntArray(length);
    32     
    33     if( !(ret && ret->construct()) ) 
    34     {
    35         delete ret;
    36         ret = 0;
    37     }
    38         
    39     return ret;
    40 }
    41 
    42 int IntArray::length()
    43 {
    44     return m_length;
    45 }
    46 
    47 bool IntArray::get(int index, int& value)
    48 {
    49     bool ret = (0 <= index) && (index < length());
    50     
    51     if( ret )
    52     {
    53         value = m_pointer[index];
    54     }
    55     
    56     return ret;
    57 }
    58 
    59 bool IntArray::set(int index, int value)
    60 {
    61     bool ret = (0 <= index) && (index < length());
    62     
    63     if( ret )
    64     {
    65         m_pointer[index] = value;
    66     }
    67     
    68     return ret;
    69 }
    70 
    71 IntArray::~IntArray()
    72 {
    73     delete[]m_pointer;
    74 }

    针对上面的问题,我们如何使用一个行之有效的办法解决?

    二阶构造:

    -工程开发中的构造函数过程可分为

    1.资源无关的初始化操作

      -不可能出现异常情况的操作

    2.需要使用系统资源的操作

      -可能出现异常情况,如:内存申请,访问文件。

    步骤:

    创建对象——》资源无关初始操作——》资源相关初始操作——》资源申请成功——》true——》返回对象

    代码:

     1 #include <stdio.h>
     2 
     3 class TwoPhaseCons 
     4 {
     5 private:
     6     TwoPhaseCons() // 第一阶段构造函数
     7     {   
     8     }
     9     bool construct() // 第二阶段构造函数
    10     { 
    11         return true; 
    12     }
    13 public:
    14     static TwoPhaseCons* NewInstance(); // 对象创建函数
    15 };
    16 
    17 TwoPhaseCons* TwoPhaseCons::NewInstance() 
    18 {
    19     TwoPhaseCons* ret = new TwoPhaseCons();
    20 
    21     // 若第二阶段构造失败,返回 NULL    
    22     if( !(ret && ret->construct()) ) 
    23     {
    24         delete ret;
    25         ret = NULL;
    26     }
    27         
    28     return ret;
    29 }
    30 
    31 
    32 int main()
    33 {
    34     TwoPhaseCons* obj = TwoPhaseCons::NewInstance();
    35     
    36     printf("obj = %p
    ", obj);
    37 
    38     delete obj;
    39     
    40     return 0;
    41 }

    小结:

    -构造函数只能决定对象的初始化状态;

    -构造函数中初始化操作的失败不影响对象的产生;

    -初始化不完全的半成品对象是Bug的重要来源;

    -二阶构造人为的将初始化过程分为两部分;

    -二阶构造能够确保创建的对象都是完整初始化的。

  • 相关阅读:
    美女检测器
    汉字动画程序的原理
    值类型不是值类型(ValueType is NOT a Value Type):闲谈.Net类型
    PowerShell 简介
    Visual Studio 2012 RC 发布
    使用 MvcMiniProfiler 监控EF 4.1 with MySQL Provider
    NuGet安装及简单使用
    发布自己的NuGet程序
    Qizmt 单机及分布式部署注意事项
    JDynamic :支持Json反序列化为Dynamic对象
  • 原文地址:https://www.cnblogs.com/lemaden/p/10117583.html
Copyright © 2020-2023  润新知