构造函数只提供自动初始化成员变量的机会,不能保证初始化逻辑一定成功,执行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;
}