二阶构造模式

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

构造函数:

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\n", t1.getI());
40         printf("t1.mj = %d\n", 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\n", obj);
37
38     delete obj;
39
40     return 0;
41 }

小结:

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

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

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

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

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

原文地址:https://www.cnblogs.com/lemaden/p/10117583.html

时间: 2024-11-11 22:20:03

二阶构造模式的相关文章

C++之二阶构造模式

前言:C++中经常会因为调用系统资源失败导致出现BUG,所以在类调用构造函数需要分配系统资源时会出现BUG,从而导致类对象虽然被创建,但是只是个半成品,为了避免这种情况需要使用二阶构造模式 二阶构造模式 源码如下 1 // 二阶构造.cpp : 定义控制台应用程序的入口点. 2 // 3 4 #include "stdafx.h" 5 #include<iostream> 6 7 using namespace std; 8 9 class test 10 { 11 pri

第27课 二阶构造模式

1. 构造函数的回顾 (1)关于构造函数 ①类的构造函数用于对象的初始化 ②构造函数与类同名并且没有返回值(思考:无返回值如何判断构造函数的执行结果?) ③构造函数在对象定义时自动被调用 [编程实验]异常的构造函数 #include <stdio.h> class Test { private: int mi; int mj; bool mStatus; public: Test(int i, int j):mStatus(false) { mi = i; return;//return,会导

C++--二阶构造模式

A.关于构造函数1.类的构造函数用于对象的初始化2.构造函数与类同名并且没有返回值3.构造函数在对象定义时被自动被调用Q.问题的出现1.如何判断构造函数的执行结果?2.在构造函数中执行return语句会发生什么?3.构造函数执行结束是否意味着对象构造成功?代码示例 #include <iostream> using namespace std; class Test { int mi; int mj; public: Test(int i, int j) { mi = i; mj = j }

第27课二阶构造模式(上)---------出现的背景

构造函数的回顾关于构造函数——类的构造函数用于对象的初始化——构造函数与类同名并且没有返回值——构造函数在对象定义时自动被调用 问题:1. 如何判断构造函数的执行结果?   目前来说,没有办法来判断构造函数的执行结果2. 在构造函数中执行return语句会发生什么?    在构造函数中可以存在return语句,return之后下面的代码就无法执行,会影响对象的初始状态3. 构造函数执行结束是否意味着对象构造成功?   对象的诞生与构造函数的执行结果是没有任何关系的.如果构造函数没有执行成功,只会

EBS OAF 开发中的OAQueryBean的三种构造模式

EBS OAF 开发中的OAQueryBean的构造模式 (版权声明,本人原创或者翻译的文章如需转载,如转载用于个人学习,请注明出处:否则请与本人联系,违者必究) 当你为pageLayout区域添加一个query 区域时,OAF框架生成一个oracle.apps.fnd.framework.webui.beans.layout.OAQueryBean对象,它依赖于它的配置,并通过一个子控件table, advanced table或者HGrid来实现simple search, advanced

C++二阶构造函数

转自:http://blog.51cto.com/9291927/1896411 一.构造函数的问题 构造函数存在问题: A.构造函数只提供自动初始化成员变量的机会 B.不能保证初始化逻辑一定成功,如申请系统资源可能失败 C.执行return语句后构造函数立即结束 构造函数创建的对象可能是半成品对象,半成品对象是合法的对象,但是是程序bug的来源之一.因此实际工程开发过程中使用二阶构造模式. 二.二阶构造模式 由于构造函数存在的潜在问题,实际工程开发中类对象的构造过程如下: A.资源无关的初始化

C++语言(03)——对象的构造

对象的构造(上) 成员变量的初始值 (1)从程序设计的角度来看,对象只是变量,定义对象就是定义变量,所以:在栈上创建对象时,成员变量初始值为随机值在堆上创建对象时,成员变量初始值为随机值在静态数据区上创建对象时,成员变量初始值为0(2)全局变量和static修饰的局部变量存储在静态数据区,没有显式初始化其值为0(bss/ZI段) /** 从程序设计的角度来看,对象只是变量,定义对象就是定义变量,所以: 在栈上创建对象时,成员变量初始值为随机值 在堆上创建对象时,成员变量初始值为随机值 在静态数据

第38课 Qt中的事件处理(上)

1. GUI程序原理回顾 (1)图形界面应用程序的消息处理模型 (2)思考:操作系统发送的消息如何转变为Qt信号 2. Qt中的事件处理 (1)Qt平台将系统产生的消息转换为Qt事件 ①Qt事件是一个QEvent的对象 ②Qt事件用于描述程序内部或外部发生的动作 ③任意的QObject对象都具备事件处理的能力 (2)GUI应用程序的事件处理方式 ①Qt事件产生后立即被分发到QWidget对象 ②QWidget中的event(QEvent*)进行事件处理 ③event()根据事件类型的不同,调用不

第九课、计算器界面代码重构

一.重构的概念 1.重构是以改善代码质量为目的代码重写 (1).使其软件的设计和架构更加合理 (2).提高软件的扩展性和维护性 2.代码实现和代码重构的不同 (1).代码实现:按照设计编程实现,重在实现功能 (2).代码重构:以提高代码质量为目的软件架构优化 (3).区别 A.代码实现时不考虑架构的好坏,只考虑功能的实现 B.代码重构时不影响已实现的功能,只考虑架构的改善 3.软件开发的过程 (1).从工程的角度对软件开发中的活动进行定义和管理 4.什么样的代码需要重构 (1).当发现项目中重复