二阶构造模式(一种小方法)设计模式就是设计方法(前人总结行之可行的一种方法)
构造函数
- 类的构造函数用于对象的初始化
- 构造函数与类同名并且没有返回值
- 构造函数在对象定义是自动被调用
问题
- 如何判断构造函数的执行结果?
- 在构造函数中执行 return 语句会发生什么?
- 构造函数执行结束是否意味着对象构造成功?
没有办法判断构造函数的执行结果,可以强行定义一个变量,然后去判断! 如下:
class Test
{
private:
int m_i;
int m_j;
bool m_status;
public:
Test(int i, int j) : m_status(false)
{
m_i = i;
m_j = j;
// return; 如果这里执行这个语句,构造函数结束,不能保证初始成功
m_status = true;
}
int getI()
{
return m_i;
}
int getJ()
{
return m_j;
}
bool getstatus()
{
return m_status;
}
};
int main()
{
Test test(1, 2);
if(test.getstatus())
{
cout << "m_i = " << test.getI() << endl;
cout << "m_j = " << test.getJ() << endl;
}
return 0;
}
构造函数
- 只提供自动初始化成员变量的机会
- 不能保证初始化逻辑一定成功
- 执行return语句后构造函数立即结束
因此构造函数只能决定的只是对象的初始化状态,而不是对象的诞生!!!!
半成品对象的概念
- 初始化操作不能按照预期完成而得到的对象
- 半成品对象是合法的C++对象,也是 Bug 的重要来源
半成品对象不是预期的,其语法是合法的。
二阶构造,工程开发中的构造过程可分为
- 资源无关的初始化操作
不可能出现异常情况的操作
- 需要使用系统资源的操作
可能出现异常情况,如:内存申请,访问文件
将构造函数一分为二,程序执行流程
// 二阶构造模型
class TwoPhasecons
{
private:
// 把构造函数私有;创建静态对象函数
TwoPhasecons() // 第一阶段构造函数
{}
bool construct() // 第二阶段构造函数
{
return true;
}
public:
static TwoPhasecons* NewInstance(); // 对象创建函数
};
// .c文件
TwoPhasecons* TwoPhasecons::NewInstance()
{
TwoPhasecons* ret = new TwoPhasecons()
// 若第二阶构造失败,怎删除返回
if( !(ret && (ret->construct())))
{
delete ret;
ret = NULL;
}
}
//使用操作
TwoPhasecons obj;
// error 因为生成对象的的构造函数是私有的。(main函数不是这个类的函数)
TwoPhasecons* obj = new TwoPhasecons();
//如果自己去new一个的话还是编译报错,因为new出来的还是会调用构造函数,但是构造函数是私有的。
TwoPhasecons* obj = TwoPhasecons::NewInstance();
// ok
// 此时obj 是合法的对象,并且在是在堆上申请的
对象一般占有很大的空间,所以一般不适合放在栈上的,一般放在堆上(所以二阶开发对工程很有用)
二阶构造函数要么返回合法的对象,要么返回空
小结
- 构造函数只能决定对象的初始化状态
- 构造函数中初始化操作的失败不影响对象的诞生
- 初始化不完全的半成品对象是Bug 的重要来源
- 二阶构造人为的讲初始化过程分为两部分
- 二阶构造能够确保创建的对象都是完整初始化的