c++类的二阶构造

 c++类的二阶构造函数主要适用于在构造函数申请系统资源的场景。普通构造函数的作用是初始化对象,若在初始化过程中不能按照程序员预期的进行,那么将会得到一个半成品对象。以下面代码为例:

using namespace std;
class SecondOrder
{
private:
    char* pchar;
    int val;

public:
    SecondOrder()
    {
        pchar = new char;       
        val = 5;
    }

    ~SecondOrder()
    {
        delete pchar;
        pchar = NULL;
    }

    void SetValue(char c, int i)
    {
        *pchar = c;
        val = i;
    }

    void PrintValue(void)
    {
        cout << "*pchar = " << *pchar << endl;
        cout << "val = " << val << endl;
    }
};

int main(void)
{
    SecondOrder s;
    s.SetValue('6', 9);
    s.PrintValue();

    return 0;
}

 编译运行:
这里写图片描述

 构造函数中执行动态分配,这就意味着存在分配异常的可能性,即pchar指针可能为NULL。那么:
 (1) 构造函数无返回值,类的定义者无法知道构造函数是否执行成功。要表示这种错误,只能通过类中某个状态量表示
 (2) 若判断动态分配失败后直接return,还会导致val未被初始化,所以形成半成品对象,对半成品对象的任务操作都可能引发段错误

 这时候可以采用二阶构造的方法:
 二阶构造即将类的构造过程分为与资源无关的初始化操作和需要使用系统资源的操作,前者不可能出现异常现象,后者则可能会申请内存失败、文件打开失败等异常。

using namespace std;
class SecondOrder
{
private:
    char* pchar;
    int val;

    SecondOrder()       //实现第一阶段的构造
    {
        val = 5;
    }

    bool construct()    //实现第二阶段的构造
    {
        pchar = new char;       
        if (NULL == pchar)
            return false;
        return true;
    }

public:
    static SecondOrder* instance()  //类的使用者要调用的接口,用于返回对象的指针
    {
        SecondOrder* ret = new SecondOrder();

        if (!(ret && ret->construct())) //两个new操作只要任务失败,ret都将为NULL
        {
            delete ret;
            ret = NULL;
        }
        return ret;
    }

    ~SecondOrder()
    {
        delete pchar;
        pchar = NULL;
    }

    void SetValue(char c, int i)
    {
        *pchar = c;
        val = i;
    }

    void PrintValue(void)
    {
        cout << "*pchar = " << *pchar << endl;
        cout << "val = " << val << endl;
    }
};

int main(void)
{
    SecondOrder *ps = SecondOrder::instance();
    if (ps != NULL)
    {
        ps->SetValue('6', 9);
        ps->PrintValue();
    }
    else
        cout << "ps = NULL" << endl;

    return 0;
}

 用二阶构造的方式设置类的构造函数,就不能让用户利用该类直接生成对象,因为这样操作会使得默认为构造函数被调而忽略了二阶构造的construct()函数。用户要生成对象需要使用类中的静态函数instance(),instance()执行new对象操作,此时会调用默认构造函数,在此函数中实现不可能会出现异常的操作,称为一阶构造。new成功的前提下调用construct()函数,在此函数中实现可能会出现异常的操作,称为二阶构造。在确保一阶构造和二阶构造都执行成功的前提下返,instance才返回new的对象的地址,反之返回NULL。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值