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;
}
相关推荐
bnmoel2 小时前
C++ 基础入门篇(二):引用
开发语言·c++·引用·底层
richard_yuu2 小时前
AOI 实战第六篇:.onnx 到 C++ 的最后一公里
c++·深度学习·yolo
wuminyu2 小时前
Kafka配置TLS/SSL加密传输时零拷贝失效分析
java·linux·c语言·jvm·c++
影视飓风TIM2 小时前
C++ 智能指针:auto_ptr / unique_ptr / shared_ptr / weak_ptr 原理与使用
开发语言·c++
一木 之林2 小时前
李沐《动手学深度学习》知识卡合集:从 Softmax 回归到房价实战(第24-50集)
开发语言·c++·人工智能
keyipatience3 小时前
5种IO模型与阻塞IO,select,poll,epoll,LT和ET模式
linux·服务器·网络·数据结构·c++·算法
汉克老师3 小时前
CSP-J 初赛(以满分为目标):第三十八课《数学与逻辑①——排列还是组合?先搞清楚“选”与“排”》
c++·csp-j·小学生·学c++编程
qeen873 小时前
【C++】智能指针介绍
开发语言·c++·笔记·指针
Lionel_Coder3 小时前
matmul 总体设计
c++
Dream Cosmos3 小时前
C++ 中 static 关键字的作用与使用规则
linux·c++