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;
}
相关推荐
码匠许师傅5 小时前
【C++ 面试真题】26. 聊聊 C++ 的智能指针
java·c++·面试
夜不会漫长9 小时前
C++入门(1)
开发语言·c++·算法
旖旎夜光11 小时前
LeetCode 852:山脉数组的峰顶索引(二分查找) —— 题解
数据结构·c++·算法·leetcode·二分查找
..Dauntless..11 小时前
【C++】继承——基类和派生类的配合
开发语言·c++·算法
程与留11 小时前
05_Qt 核心模块概览——Qt Core、Gui、Widgets、Quick 的职责划分
c++·qt
buhuizhiyuci12 小时前
【QT-百日筑基篇】修真世界摸爬滚打多年,终于黄天不负有心人,突破炼器中期——常用控件QWight的属性
开发语言·c++·qt·gui·图形化
冻柠檬飞冰走茶15 小时前
《数据结构实验指导-C++语言版》 求单链表list中的元素个数,即表长
开发语言·数据结构·c++·算法·list
_Narcissus_15 小时前
动态规划初探(含完整代码实现)
c语言·数据结构·c++·算法·动态规划·背包问题·最短路径
法哥201216 小时前
用 C++ 控制 CMW100,到底在干什么?
开发语言·c++
_Narcissus_17 小时前
枚举和模拟算法笔记
c语言·数据结构·c++·笔记·算法·模拟·枚举