C++——二阶构造模式

构造函数只提供自动初始化成员变量的机会,不能保证初始化逻辑一定成功,执行return后构造函数立即结束; 构造函数能决定的只是对象的初始状态,而不是对象的诞生

判断对象是否构造成功

法一:定义一个成员变量mStatus初始值为false,构造成功之后改为true

复制代码
#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 getStatus() {
		return mStatus;
	}
};
int main() {
	Test t1(1, 2);
	if (t1.getStatus()) {
		printf("t1.mi=%d\n", t1.getI());
		printf("t1.mj=%d\n", t1.getJ()); //打印为空
	}
	return 0;
}

2.工程开发中构造过程可分为:

(1)第一阶段构造:资源无关的初始化操作(不可能出现异常情况的操作)

(2)第二阶段构造:需要使用系统资源的操作,可能出现异常情况,如:内存申请,访问文件

如果资源申请成功就返回对象,不成功就返回空

此时,创建的所有对象都放在堆空间中

示例:

复制代码
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 = nullptr;
	}
	return ret;
}
int main() {
	TwoPhaseCons* obj = TwoPhaseCons::NewInstance();
	printf("obj=%p\n", obj);
	return 0;
}

3.示例:数组类加强

开发一个数组类解决原生数组的安全性问题:提供函数获取数组长度、获取数组元素、设置数组元素

IntArray.h

复制代码
class IntArray {
private:
	int m_length;
	int* m_pointer;

	IntArray(int len);
	IntArray(const IntArray& obj);
	bool construct();
public:
	static IntArray* NewInstance(int length);
	int length();
	bool get(int index, int& value); //index是数组下标
	bool set(int index, int value);
	void free();
};

IntArray.cpp

复制代码
#include "intArray.h"
IntArray::IntArray(int len) {
	m_length = len;
}
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* ret = new IntArray(length);
	//若第二阶段构造失败,返回NULL
	if (!(ret && ret->construct())) {
		delete ret;
		ret = nullptr;
	}
	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;
}
void IntArray::free() {
	delete[]m_pointer;
}

main.cpp

复制代码
#include <stdio.h>
#include "intArray.h"
int main() {
	IntArray* a = IntArray::NewInstance(5);
	printf("a.length=%d\n", a->length()); //5
	a->set(0, 1); 
	for (int i = 0; i < a->length(); i++) {
		int v = 0;
		a->get(i, v);
		printf("a[%d]=%d\n", i, v); //a[0]=1 a[1]=0 a[2]=0 a[3]=0 a[4]=0
	}
	delete a;
	return 0;
}
相关推荐
clint4562 天前
C++进阶(1)——前景提要
c++
夜悊2 天前
C++代码示例:进制数简单生成工具
c++
郝学胜_神的一滴2 天前
CMake 021: IF 条件判据详诠
c++·cmake
_wyt0013 天前
洛谷 B3930 [GESP202312 五级] 烹饪问题 题解
c++·gesp
玖玥拾3 天前
C/C++ 数据结构(七)栈、容器适配器
c语言·数据结构·c++··容器适配器
один but you3 天前
constexpr函数
c++
凡人叶枫3 天前
Effective C++ 条款41:了解隐式接口和编译期多态
java·开发语言·c++·effective c++
凡人叶枫3 天前
Effective C++ 条款42:了解 typename 的双重意义
java·linux·服务器·c++
小胖xiaopangss3 天前
BRpc使用
c++·rpc
-森屿安年-3 天前
63. 不同路径 II
c++·算法·动态规划