0.目录

1.构造函数与半成品对象

2.二阶构造

3.小结

1.构造函数与半成品对象

关于构造函数:

  • 类的构造函数用于对象的初始化
  • 构造函数与类同名并且没有返回值
  • 构造函数在对象定义时自动被调用

问题:

  1. 如何判断构造函数的执行结果?
  2. 在构造函数中执行return语句会发生什么?
  3. 构造函数执行结束是否意味着对象构造成功?

(没有办法判断构造函数的执行结果,构造函数执行结束不意味着对象构造成功)

用一个状态来表示对象是否构造成功:

#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 status()
{
return mStatus;
}
}; int main()
{
Test t1(1, 2); if( t1.status() )
{
printf("t1.mi = %d\n", t1.getI());
printf("t1.mj = %d\n", t1.getJ());
} return 0;
}

输出结果为空。

构造函数:

  • 只提供自动初始化成员变量的机会
  • 不能保证初始化逻辑一定成功
  • 执行return语句后构造函数立即结束

构造函数能决定的只是对象的初始状态,而不是对象的诞生!!

半成品对象的概念:

  • 初始化操作不能按照预期完成而得到的对象
  • 半成品对象是合法的C++对象,也是Bug的重要来源

2.二阶构造

工程开发中的构造过程可分为:

  • 资源无关的初始化操作

    1. 不可能出现异常情况的操作
  • 需要使用系统资源的操作
    1. 可能出现异常情况,如:内存申请,访问文件

二阶构造:

二阶构造示例一:

二阶构造示例二:

示例代码:

#include <stdio.h>

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 = NULL;
} return ret;
} int main()
{
TwoPhaseCons* obj = TwoPhaseCons::NewInstance(); printf("obj = %p\n", obj); delete obj; return 0;
}

运行结果为:

[root@bogon Desktop]# g++ test.cpp
[root@bogon Desktop]# ./a.out
obj = 0xd4f010

若是二阶构造失败了呢?

#include <stdio.h>

class TwoPhaseCons
{
private:
TwoPhaseCons() // 第一阶段构造函数
{
}
bool construct() // 第二阶段构造函数
{
return false;
}
public:
static TwoPhaseCons* NewInstance(); // 对象创建函数
}; TwoPhaseCons* TwoPhaseCons::NewInstance()
{
TwoPhaseCons* ret = new TwoPhaseCons(); // 若第二阶段构造失败,返回 NULL
if( !(ret && ret->construct()) )
{
delete ret;
ret = NULL;
} return ret;
} int main()
{
TwoPhaseCons* obj = TwoPhaseCons::NewInstance(); printf("obj = %p\n", obj); delete obj; return 0;
}

运行结果为:

[root@bogon Desktop]# g++ test.cpp
[root@bogon Desktop]# ./a.out
obj = (nil)

会返回一个空。

使用二阶构造模式后,对象只能在堆空间上创建,不能在栈上产生了。这恰恰是工程里面最重要的一个决定,因为在工程中,对象往往是比较巨大的,不适合放在栈空间当中,都应该放到堆空间里面去。

3.小结

  • 构造函数只能决定对象的初始化状态
  • 构造函数中初始化操作的失败不影响对象的诞生
  • 初始化不完全的半成品对象是Bug的重要来源
  • 二阶构造人为的将初始化过程分为两部分
  • 二阶构造能够确保创建的对象都是完整初始化的

C++解析(15):二阶构造模式的更多相关文章

  1. C++之二阶构造模式

    前言:C++中经常会因为调用系统资源失败导致出现BUG,所以在类调用构造函数需要分配系统资源时会出现BUG,从而导致类对象虽然被创建,但是只是个半成品,为了避免这种情况需要使用二阶构造模式 二阶构造模 ...

  2. C++ 二阶构造模式

    1.如何判断构造函数的执行结果? 构造函数没有返回值,所以不能通过返回值来判断是构造函数是否构造成功. 如果给构造函数强行加入一个返回值,用来表示是否构造成功.这样确实能够反映出构造的结果,但是不够优 ...

  3. 14.C++-二阶构造模式、友元(详解)

    首先回顾以前所学的构造函数 类的构造函数用于对象的初始化 构造函数与类同名并且没有返回值 构造函数在定义时被自动调用 由于构造函数没有返回值不能判断执行结果,所以不能保证初始化对象能否成功 比如: c ...

  4. Spark Streaming揭秘 Day34 解析UI监听模式

    Spark Streaming揭秘 Day34 解析UI监听模式 今天分享下SparkStreaming中的UI部分,和所有的UI系统一样,SparkStreaming中的UI系统使用的是监听器模式. ...

  5. 第15章 迭代器模式(Iterator Pattern)

    原文 第15章 迭代器模式(Iterator Pattern) 迭代器模式(Iterator Pattern)    概述: 在面向对象的软件设计中,我们经常会遇到一类集合对象,这类集合对象的内部结构 ...

  6. 【省带宽、压成本专题】深入解析 H.265 编码模式,带你了解 Apple 全面推进 H.265 的原因

    过去几年,又拍云一直在点播.直播等视频应用方面潜心钻研,取得了不俗的成果.我们结合点播.直播.短视频等业务中的用户场景,推出了"省带宽.压成本"系列文章,从编码技术.网络架构等角度 ...

  7. JSON.stringify()方法是将一个javascript值(对象或者数组)转换成为一个JSON字符串;JSON.parse()解析JSON字符串,构造由字符串描述的javascript值或对象

    JSON.stringify()方法是将一个javascript值(对象或者数组)转换成为一个JSON字符串:JSON.parse()解析JSON字符串,构造由字符串描述的javascript值或对象

  8. Java设计模式(15)备忘录模式(Memento模式)

    Memento定义:memento是一个保存另外一个对象内部状态拷贝的对象,这样以后就可以将该对象恢复到原先保存的状态. Memento模式相对也比较好理解,我们看下列代码: public class ...

  9. javascript创建对象之函数构造模式和原型模式结合使用(四)

    创建自定义类型的常见方式就是组合使用构造函数模式与原型模式一起使用. 构造函数模式用于定义实例对象的特有的部分(属性和方法),原型模式用于定义共享的部分. 这样最大限度的节省了内存的开销. funct ...

随机推荐

  1. WPF 如何自定义一个弹框

    ------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 简述: 手工以原生Grid的方式,自定义了一个仿弹窗效果,优点可以自定义,缺点需要自己实现以及维护整个弹窗的效 ...

  2. Visual Studio设置字体及护眼背景色

    打开vs 菜单栏选择: 工具 -> 选择 -> 环境 -> 字体和颜色,如图所示 字体可以如上选择,背景色选择项背景,点击自定义,如下设置即可.

  3. spark重点知识

    1 scala 2 spark rdd 3 sprak core 4 性能优化 5 spark sql 6 spark streaming 掌握程度-精通的理解:

  4. CsvHelper文档-6类型转换

    CsvHelper文档-6类型转换 CsvHelper使用类型转换器来转换string到对象,或者对象到string: ITypeConverter 类型转换器的结构,必须实现: public int ...

  5. PIL包中图像的mode参数

    在这里的第一篇. 这篇的是为了说明PIL库中图像的mode参数. 我做的事情是: 在本地找了jpg的图,convert为不同mode,将不同的图截取做了个脑图,有个直观的感觉吧. 把不同mode的图通 ...

  6. Bean的装配

    1.可以从ApplicationContext上下文获取和bean工厂获取容器,bean工厂只建议在移动端应用使用. 2.如果使用的是applicationContext配置的是bean,如果作用域是 ...

  7. Linux学习——echo和read命令用法

    转载自http://www.runoob.com/linux/linux-comm-read.html http://www.178linux.com/76331 echo命令 本文列举了echo命令 ...

  8. 第五次作业psp

    psp 进度条 代码累积折线图 博文累积折线图 psp饼状图 团体合作体会:经过这几天的团队,我感受良多.发现团队协作是一件非常让人兴奋的事情.团队成员们互相帮助,互相协作,让我感受最深的就是当自己为 ...

  9. Linux 下web开发环境搭建-jdk环境搭建

    Centos 7 附:windows 下jdk环境变量 CLASSPATH .;%JAVA_HOME%\lib;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools ...

  10. iframe高度自适应的6个方法

    原文链接:http://caibaojian.com/iframe-adjust-content-height.html JS自适应高度,其实就是设置iframe的高度,使其等于内嵌网页的高度,从而看 ...