C++理解(4)--C++的二阶构造模式

C++的二阶构造模式

首先明白构造函数是什么:

  • 类的构造函数用来对象的初始化
  • 构造函数与类同名并且没有返回值
  • 构造函数的在创建对象时候自动被调用

先抛出问题:
构造函数执行结果是什么?
构造函数中加上return会发生什么?
构造函数的执行结束是否意味着对象构造成功?
先上代码:

#include <stdio.h>

class Test
{
    int mi;
    int mj;
public:
    Test(int i, int j)
    {
        mi = i;
        mj = j;
    }
    int getI()
    {
        return mi;
    }
    int getJ()
    {
        return mj;
    }
};

int main()
{  
    Test t1(1, 2);
	    printf("t1.mi = %d\n", t1.getI());
        printf("t1.mj = %d\n", t1.getJ());
    return 0;
}

上述的代码为简单的C++代码。结果是

t1.mi = 1
t1.mj = 2

对于上述的问题,我们要加一个return语句会发生什么?

#include <stdio.h>

class Test
{
    int mi;
    int mj;
public:
    Test(int i, int j)
    {
        mi = i;
        return;
        mj = j;
    }
    int getI()
    {
        return mi;
    }
    int getJ()
    {
        return mj;
    }
};

int main()
{  
    Test t1(1, 2);
	    printf("t1.mi = %d\n", t1.getI());
        printf("t1.mj = %d\n", t1.getJ());
    return 0;
}

结果:

t1.mi = 1
t1.mj = 2527220

mj的结果不是2.表明构造函数执行在return这个函数就结束了
因此构造函数只能决定对象的初始状态,而不是决定对象的诞生。
在加return之后,t1这个对象并没有完全构造,所以是不可以正常使用的。因此他叫半成品对象

半成品对象的概念:

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

半成品对象是合法的C++对象,但是同时它也是Bug的重要来源

一般企业中最难以调试的Bug,一是野指针(后面文章会写),其次就是这个半成品对象带来的Bug。 为了避免这样的结果,我们要引出二阶构造的含义。

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

资源无关的初始化操作(即不可能出现异常情况的操作)肯定不会出错的情况
需要使用系统资源的操作(即可能出现异常情况,如:内存申请,访问文件)怀疑出错的

他的大致流程如下:
在这里插入图片描述
先看一下代码:

#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 = TwoPhaseCons::NewInstance();
    
    printf("obj = %p\n", obj);

    delete obj;
    
    return 0;
}

第一阶段的构造函数与第二阶段的构造函数放在private里面,外部无法调用
但是在public中,定义的static TwoPhaseCons* NewInstance(); 返回的是TwoPhaseCons型的对象.那么通过可以调用构造函数的private。因为处于NewInstance内部,所以它可以调用构造函数。

TwoPhaseCons* ret = new TwoPhaseCons();

在main函数中有一句话:TwoPhaseCons* obj = TwoPhaseCons::NewInstance();这是调用NewInstance()函数创建obj 对象,因为构造函数TwoPhaseCons为private类型,所以想创建对象,必须用public中的静态创建函数:static TwoPhaseCons* NewInstance();
**

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

**

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值