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. Swift - 重写导航栏返回按钮

    // 重写导航栏返回按钮方法 func configBackBtn() -> Void { // 返回按钮 let backButton = UIButton(type: .custom) // ...

  2. Drupal views 学习之初识

    1. 简介 用过Yii框架的同学,应该都会用到过GridView和ListView组件.可以很方便的用网格或列表展示内容. 例如淘宝: 网格显示 列表显示 2. 使用view可以方便的配出类似上面的展 ...

  3. ps 图层解锁后变成全格子(全透明)的解决方法

    其实是因为同时打开了好几个ps文件正在编辑中,所以解决方法就是重启ps,然后单独编辑一个文件,解锁后就不会再出现这种情况能,就能正常编辑了

  4. EOJ3650 转机折扣(26进制,字符串)

    题面 看成26进制,把较小的那个字符串加1 strcmp(s1,s2)s1和s2有大小时,不一定都是返回1或者-1.....这个地方wa了好几次没有发现 #include<bits/stdc++ ...

  5. (转)python+opencv实现动态物体追踪

    原文链接:https://blog.csdn.net/cike14/article/details/50649811 import cv2 import numpy as np camera=cv2. ...

  6. hadoop 基础入门

    启动:   格式化节点:bin/hdfs namenode -format   全部启动:sbin/start-dfs:datanode.namenode                    sbi ...

  7. 从武侠中的兵器看待数据访问工具——Hibernate Spring.Data Mybatis

    <泪痕剑>第31集,卓爷大谈自己的兵器,我从中摘录,觉得非常受用. “你错了,我们和武器之间的关系,就好像选择情人一样,不管是否擅长,都要用感情. 我少年时候用刀,青年时候仍用刀,不知道用 ...

  8. Windows操作系统C盘占用空间过多

    Windows操作系统C盘占用空间过多 大部分的windows电脑用户在长时间使用PC时都会遇到一个问题,就是C盘占用的空间会越来越多,乃至占满整个C盘. 后来在百度了一波,发现各种方法都试过了,也不 ...

  9. openvpn部署

    原文发表于cu:2016-03-29 参考文档: 安装:http://qicheng0211.blog.51cto.com/3958621/1575273 安装:http://www.ipython. ...

  10. 互评Alpha版本——基于spec评论作品

    组名:可以低头,但没必要 组长:付佳 组员:张俊余  李文涛  孙赛佳  田良  于洋  刘欣  段晓睿 一.二次元梦之队----I DO 在测评该项目时,我们组索要了该组的apk程序,安装之后我就开 ...