最近踩到一坑,编译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;
}
网友评论