前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C++:二阶构造函数

C++:二阶构造函数

作者头像
王强
发布2019-03-04 17:15:04
5590
发布2019-03-04 17:15:04
举报
文章被收录于专栏:Python爬虫实战Python爬虫实战

1、构造函数的问题2、二阶构造模式

类的构造函数是类的一种特殊的成员函数,它会在每次创建类的新对象时执行。最常见的操作是在构造函数中为类的成员变量进行赋值,如果还想再构造函数中进行一些其他操作,可能会出现一些问题。

1、构造函数的问题

下面通过实例讨论一下构造函数存在的问题:

代码语言:javascript
复制
// 二阶构造模式.cpp: 定义控制台应用程序的入口点。
//
#include <windows.h>
#include <stdio.h>
#include <iostream>

using namespace std;

class Test
{
public:
    Test(int a, int b)
    {
        m_i = a;
        return;

        m_j = b;
    }
    int getI()
    {
        return m_i;
    }
    int getJ()
    {
        return m_j;
    }

private:
    int m_i;
    int m_j;
};

int main()
{
    Test t(1, 2);

    cout << "t.mi = " << t.getI() << endl;
    cout << "t.mj = " << t.getJ() << endl;

    system("pause");
    return 0;
}

程序输出结果:

从结果可以看出 m_j 并没有被初始化成功,构造函数执行到 “return” 语句后退出了构造函数,从而导致 m_j =b 语句并没有执行。

关于构造函数:

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

由此可见,构造函数能决定的只是对象的初始化状态,而不是对象的诞生。

2、二阶构造模式

在C++中有半成品概念,顾名思义就是未初始化完成的对象,虽然未初始化成功,但半成品对象是合法的C++对象,也是Bug的重要来源之一。

依据工程经验,我们可以将构造过程分为以下两种:

  • 资源无关的初始化操作,也就是不可能出现异常情况的操作,比如:对象初始值设置等;
  • 需要使用系统资源的操作,可能出现异常情况,比如:申请内存、读写文件等等。

根据上述构造过程,我们来看一下二阶构造的完整顺序:

从图中看出,如果进行系统资源申请操作出错,则应删除半成品对象并返回NULL,以避免出现Bug。请看下面二阶构造模式代码:

代码语言:javascript
复制
class SecondOrderConstruction
{
private:
    SecondOrderConstruction()   // 第一阶段构造函数:资源无关初始化
    {
    }
    bool construct() // 第二阶段构造函数:与系统资源有关的初始化,如申请内存、读写文件等
    {
        bool ret = true;
        // TODO: 系统资源相关操作并给ret赋值
        return ret;
    }

public:
    static SecondOrderConstruction* Instance(); // 对象创建函数
};

SecondOrderConstruction* SecondOrderConstruction::Instance()
{
    SecondOrderConstruction* instance = new SecondOrderConstruction();

    // 第二阶段构造
    if (!(instance && instance->construct()))
    {
        delete instance;        // 申请资源失败,删除半成品对象
        instance = NULL;        // 返回NULL
    }
    return instance;
}

int main()
{
    SecondOrderConstruction* obj = SecondOrderConstruction::Instance();
    cout << "obj=" << obj << endl;
    delete obj;

    system("pause");
    return 0;
}

运行结果:

函数解读: 二阶构造的方式设置类的构造函数,使得用户不能利用该类直接生成对象,因为这样操作会使得默认为构造函数被调而忽略了二阶构造的 construct() 函数。用户要生成对象需要使用类中的静态函数 Instance(),Instance() 执行 new 对象操作,此时会调用默认构造函数,在此函数中实现不可能会出现异常的操作,称为一阶构造。new 成功的前提下调用 construct() 函数,在此函数中实现可能会出现异常的操作,称为二阶构造。在确保一阶构造和二阶构造都执行成功的前提下,Instance 才返回 new 的对象的地址,反之返回NULL。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-01-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 C与Python实战 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、构造函数的问题
  • 2、二阶构造模式
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档