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;
}
相关推荐
郝学胜-神的一滴2 小时前
Python中的“==“与“is“:深入解析与Vibe Coding时代的优化实践
开发语言·数据结构·c++·python·算法
zmzb01032 小时前
C++课后习题训练记录Day109
开发语言·c++
sycmancia2 小时前
C++——类的静态成员变量、静态成员函数
c++
_风华ts2 小时前
C++智能指针
c++·智能指针
小冻梨6662 小时前
ABC445 C - Sugoroku Destination题解
c++·算法·深度优先·图论·
白太岁2 小时前
C++:(4) 内存布局、编译流程、关键字及其链接性
c语言·汇编·jvm·c++
白太岁3 小时前
Muduo:(4) 主从 Reactor、事件循环、跨线程无锁唤醒及其线程池
c++·网络协议·tcp/ip
喜欢吃燃面3 小时前
基础算法:枚举(上)
c++·学习·算法
郝学胜-神的一滴3 小时前
计算思维:数字时代的超级能力
开发语言·数据结构·c++·人工智能·python·算法