异常构造函数
构造函数的判断
#include <stdio.h>
class Test
{
int mi;
int mj;
bool mstatus;
public:
Test(int i, int j):mstatus(false)
{
mi = i;
return;//直接返回
mj = j;
mstatus = true;
}
int getI()
{
return mi;
}
int getJ()
{
return mj;
}
int status()
{
return mstatus;
}
};
int main()
{
Test t1(1,2);
if(t1.status())
{
printf("t1.getI() = %d\n", t1.getI());
printf("t1.getI() = %d\n", t1.getJ());
}
return 0;
}
构造函数
- 决定对象的初始化状态,诞生状态不确定
- 遇到return结束,不能保证逻辑一定成功
- 半成品对象(初始化不能按照预期完成得到的对象)是合法,也是bug来源
工程开发构造过程可分为
- 不使用系统资源
- 不可能出现异常操作
- 使用系统资源
- 可能出现异常操作,申请内存,打开文件
#include <stdio.h>
class TwoPhaseCons
{
private:
TwoPhaseCons() // 第一阶段构造函数
{
}
bool construct() // 第二阶段构造函数
{
return false;
}
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();//用类名访问静态成员函数,创建对象
//TwoPhaseCons *obj = new TwoPhaseCons(); //构造函数自由化了
printf("obj = %p\n", obj);
delete obj;
return 0;
}
- 用于杜绝半成品对象
#include "IntArray.h"
#include "string.h"
IntArray::IntArray(int len)
{
m_length = len;
}
IntArray::~IntArray()
{
delete[]m_pointer;
}
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::IntArray?
{
IntArray* ret = new IntArray(length);
if(!(ret && ret->construct()))
{
delete ret;
ret = NULL;
}
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;
}
#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
#include <stdio.h>
#include "IntArray.h"
int main()
{
IntArray* obj = IntArray::NewInstance(5);//创建对象
printf("obj->length() = %d\n", obj->length());
obj->set(0, 1);
for(int i=0; i<obj->length(); i++)
{
int v = 0;
obj->get(i, v);
printf("obj[%d] = %d \n", i, v);
}
delete obj;
return 0;
}
小结
- 构造函数只能决定对象的初始化状态
- 构造函数初始化失败不影响对象产生
- 初始化不完全的半成品对象是bug的主要来源
- 二阶构造人为的将初始化过程分为两部分(不产生异常与可能产生异常地方)
- 二阶构造能确保创建的对象都是完整初始化的