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;
}
相关推荐
WBluuue3 小时前
数据结构与算法:康托展开、约瑟夫环、完美洗牌
c++·算法
木子墨5163 小时前
LeetCode 热题 100 精讲 | 并查集篇:最长连续序列 · 岛屿数量 · 省份数量 · 冗余连接 · 等式方程的可满足性
数据结构·c++·算法·leetcode
王老师青少年编程4 小时前
csp信奥赛C++高频考点专项训练之贪心算法 --【线性扫描贪心】:均分纸牌
c++·算法·编程·贪心·csp·信奥赛·均分纸牌
weixin_513449965 小时前
PCA、SVD 、 ICP 、kd-tree算法的简单整理总结
c++·人工智能·学习·算法·机器人
烟锁池塘柳05 小时前
一文讲透 C++ / Java 中方法重载(Overload)与方法重写(Override)在调用时机等方面的区别
java·c++·面向对象
yolo_guo6 小时前
glog单行 30000 字节限制问题
c++
cccccc语言我来了6 小时前
C++轻量级消息队列服务器
java·服务器·c++
闻缺陷则喜何志丹6 小时前
【背包 组合】P7552 [COCI 2020/2021 #6] Anagramistica|普及+
c++·算法·背包·洛谷·组合
xiaoye-duck6 小时前
【C++:C++11】C++11新特性深度解析:从类新功能、Lambda表达式到包装器实战
开发语言·c++·c++11
一个行走的民7 小时前
C++ Lambda 表达式语法详解
c++