C++ 惯用法之 Nifty Counter

背景

C++ 中全局对象的初始化在 main 函数执行前完成,在 main 函数执行结束前销毁。在同一源码文件中全局变量的初始化顺序和其定义顺序一致;但在不同的源码文件中其初始化顺序不一致,就有可能导致代码出错。

一般解决方法

①.概述

静态局部变量只有在第一次使用时才会初始化,并且只会初始化一次,可应用该特点解决全局变量的初始化问题。

②.构造动态对象

demoClass & getDemo
{
    static demoClass * demo = new demoClass();
    return *demo;
}

该方法中,在程序结束时 demo 指向的内存会被系统强制回收,不会造成内存泄漏,但是由于其析构函数没有被调用,就有可能造成一些必要操作没有被执行,从而引发问题。

③.构造静态对象

demoClass & getDemo
{
    static demoClass  demo 
    return demo;
}

该方法中,demo 会在其所在的源码文件中的其他全局对象销毁时一起销毁,会执行析构函数,但由于不同源码文件间全局对象销毁顺序不一致,有可能引发问题。

Nifty Counter 惯用法

①.概述

Nifty Counter 惯用法的原理就是为全局变量创建一个管理对象,通过这个管理对象进行全局变量的创建和销毁。

②.代码示例

//demoClass.h

class demoClass
{
public:
  demoClass() { std::cout << "demoClass construted " << std::endl; }
  ~demoClass() { std::cout << "demoClass deconstruted " << std::endl; }

  void func(){ std::cout << "hello world " << std::endl; }
};
//demoClassInit.h

#include "demoClass.h"

extern demoClass* demo;
class demoClassInit
{
public:
  explicit demoClassInit();
  ~demoClassInit();
  
  static int demo_Counter;
};

static demoClassInit demoInit;
//demoClassInit.cpp

#include "demoClassInit.h"

demoClass* demo = nullptr;
int demoClassInit::demo_Counter = 0;

demoClassInit::demoClassInit()
{
  if (demo_Counter++ == 0) demo = new demoClass;
}

demoClassInit::~demoClassInit()
{
  if (--demo_Counter == 0) delete demo;
}
#include "demoClassInit.h"

int main()
{
  demo->func();
    return 0;
}

在这里插入图片描述

③.原理说明

在每个需要使用全局变量的源码文件中都必须引用头文件 “demoClassInit.h”,则一定会引入一个全局静态对象 demoInit,该对象会随着本源码文件中全局变量的创建和销毁调用其构造和析构方法,从而可以对全局变量 demo 生命周期进行管理:demo 一定在第一个 demoInit 对象创建时创建,在最后一个 demoInit 对象销毁时销毁,解决了全局对象的销毁及销毁顺序问题。
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值