关于全局变量定义的顺序问题

最近踩到一坑,编译cpp 文件的顺序不同导致程序异常。
假设一个类A中定义了静态成员变量,在宁一个类B的构造中需要用到这个静态成员变量。那么如果用 类B 来声明一个全局对象,就得注意了。有可能在 类B构造过程中,类A 的静态成员变量还未初始化导致异常。
解决方法, 可以在编译链接的时候保证,类A 的静态成员变量初始化的地方出现在类B 的构造前面。
logging.hpp

#pragma once
#include <iostream>
#include <functional>
#include <map>
#include <string>
using std::string;
class CLog
{
     public:
         enum class ELevel{eTrace,eDebug};
         typedef std::function<void(ELevel,const string &,const string &)> PFunction;
         CLog(ELevel value,const string &szDomain);
         void SetFunction(ELevel eLevel,PFunction Function);
    private:
        typedef std::map<ELevel,PFunction> DestMap;
        
        static DestMap m_DestMap;
        ELevel m_eLevel;
        string m_szDomain;
  
};

void InitLog();
class CLogger
{
    public:
        CLogger()
        {
            std::cout << "test: CLogger" << std::endl;
            InitLog();
         }

};

logging.cpp

#include <functional>
#include <iostream>
#include "logging.hpp"
CLog::CLog(ELevel eLevel,const std::string & szDomain)
    :m_eLevel(eLevel),m_szDomain(szDomain)
{
    std::cout <<" test: CLog" <<std::endl;
}

void CLog::SetFunction(ELevel eLevel, PFunction Function)
{
    m_DestMap[eLevel] = Function;
}


void OutputTest(CLog::ELevel eLevel ,const std::string &szDomain,const std::string &szBody)
{
    std::cout << "test : OutputTest." << std::endl;
}

void InitLog()
{
    CLog Log(CLog::ELevel::eDebug,"test");
    Log.SetFunction(CLog::ELevel::eDebug,OutputTest);
}

main.cpp

#include "logging.hpp"
#include <iostream>
//由于 Logger 构造过程中用到了 m_DestMap, 但是此时 m_DestMap 并没有初始化
//导致程序崩溃, 应该写成CLog::Destmap CLog::m_DestMap;CLogger Logger;
CLogger Logger;
CLog::DestMap CLog::m_DestMap;

int main()
{
    std::cout << " test: main"<<std::endl;
    return 0;
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容