dll 中的单件模式(3年以上工作经验请进)

会飞的鱼_2002 2007-11-02 07:32:28

小弟最近写了一个DLL,里面用单件模式写了一个日至纪录类, 然后我在该DLL中的其他类中进行使用, 结果发现如果只有一个类引用日至记录类,没有任何问题, 但是如果2个类引用就会有问题, 编译不过去,
日志纪录类实现如下:

class LogFile
{
private:
static std::ofstream log;
public:
static WriteError(const char* info);
}

请问为什么会发生这种情况
...全文
644 30 打赏 收藏 转发到动态 举报
写回复
用AI写文章
30 条回复
切换为时间正序
请发表友善的回复…
发表回复
knowledge_Is_Life 2008-05-01
  • 打赏
  • 举报
回复
好像没那么简单,呵呵.
leo201592 2008-04-28
  • 打赏
  • 举报
回复
单实例模式很简单的吧~~为什么要帖那么多代码上来呢,呵呵
YFY 2008-04-15
  • 打赏
  • 举报
回复
给你个参考,RunEvent是多线程安全的:
// LogFile.cpp: implementation of the CLogFile class.
//
/*****************************************
版权所有(C) 保留所有权利。
版 本 号: 1.0.0.1
生成日期:2007.3.28
作 者:
模块功能:写日志类
主要函数:WriteLogFile(CString strType,CString strInfo);
*******************************************/

#include "stdafx.h"
#include "LogFile.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif


/*********************************自定义变量开始*****************************************/
//CString g_strRunPath;
//CString g_strDir;
/*****************************************************************************************/
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CLogFile::CLogFile()
{
InitializeCriticalSection(&m_criticalsecRE);
// InitializeCriticalSection(&m_criticalsecSRR);
}

CLogFile::CLogFile(CString strDir)
{
g_strDir = strDir;
}

CLogFile::~CLogFile()
{
DeleteCriticalSection(&m_criticalsecRE);
// DeleteCriticalSection(&m_criticalsecSRR);
}



/*内部函数,获取当前目录*/
bool CLogFile::GetCurrentPath()
{
int i = 0;
int iLastSperate = 0;
TCHAR achCurPath[272];

GetModuleFileName(GetModuleHandle(NULL), achCurPath, 256);
for (i=0; i<256; i++)
{
if (achCurPath[i] == '\\')
{
iLastSperate = i;
}
else if(achCurPath[i] == '\0')
{
break;
}
}

if (iLastSperate > 0 && i < 256)
{
achCurPath[iLastSperate] = '\0';
}
else
{
//return;//路径过长,取路径失败
}
g_strRunPath = achCurPath;
g_strRunPath += "\\" + g_strDir + "\\";

//判断目录是否存在,不存在则创建
SECURITY_ATTRIBUTES s;
s.nLength=sizeof(SECURITY_ATTRIBUTES);
s.lpSecurityDescriptor=NULL;
s.bInheritHandle=TRUE;
if(!CreateDirectory(g_strRunPath, &s))
{
if(ERROR_ALREADY_EXISTS!=GetLastError())
{
g_strRunPath = achCurPath;
return false;//文件夹不存在但创建失败
}
}
return true;
}

/******************************************
*名称: SaveRunRecord
*功能: 写日志文件
*参数:
IN CString strDescription,事件描述
*返回值:0 成功
其它 失败
*******************************************/
//全局函数
void CLogFile::SaveRunRecord(CString strError)
{
// EnterCriticalSection(&m_criticalsecSRR);
CFile f;
BOOL bRet= TRUE;
CString strFile;
CTime tmCurr = CTime::GetCurrentTime();
char achRunRecordFile[MAX_PATH];
strFile = tmCurr.Format("%Y_%m%d.txt");
sprintf(
achRunRecordFile,
"%s%s",
g_strRunPath, strFile
);
bRet = f.Open(
achRunRecordFile,
CFile::modeCreate|CFile::modeNoTruncate|CFile::modeWrite
);
if(bRet)
{
if(f.GetLength() > 1024*2000)
{
f.Close();
f.Remove(achRunRecordFile);
bRet = f.Open(achRunRecordFile,
CFile::modeCreate|CFile::modeNoTruncate|CFile::modeWrite);
}
if(bRet)
{
CString strMsg;
CString strTime;
strTime = tmCurr.Format("%Y-%m-%d %H:%M:%S ");
strMsg.Format("%s%s\r\n", strTime, strError);
f.SeekToEnd();
f.Write((LPCTSTR)strMsg, strMsg.GetLength());
f.Close();
}
}
// LeaveCriticalSection(&m_criticalsecSRR);
}

/********************************
*名称: SaveRunRecordMonthly
*功能: 写日志文件(按月)
*参数:
IN CString strDescription,事件描述
*返回值:0 成功
其它 失败
********************************/
//全局函数
void CLogFile::SaveRunRecordMonthly(CString strError)
{
CFile f;
BOOL bRet= TRUE;
CString strFile;
CTime tmCurr = CTime::GetCurrentTime();
char achRunRecordFile[MAX_PATH];
strFile = tmCurr.Format("%Y_%m.txt");
sprintf(
achRunRecordFile,
"%s%s",
g_strRunPath, strFile
);
bRet = f.Open(
achRunRecordFile,
CFile::modeCreate|CFile::modeNoTruncate|CFile::modeWrite
);
if(bRet)
{
CString strMsg;
CString strTime;
strTime = tmCurr.Format("%Y-%m-%d %H:%M:%S ");
strMsg.Format("%s%s\r\n", strTime, strError);
f.SeekToEnd();
f.Write((LPCTSTR)strMsg, strMsg.GetLength());
f.Close();
}
}


/************************内部函数:新建多层文件夹*****
20070601
****************************/
int CreateDir(CString strDir)
{
char chFilePath[248];
CString strDir1;
int iLastSperate = 0;
int i = 0;
strcpy(chFilePath,strDir);
chFilePath[strlen(strDir)]='\0';

if(!CreateDirectory(strDir,NULL))
{
for (i=0; i<MAX_PATH-20; i++)
{
if (chFilePath[i] == '\\')
{
iLastSperate = i;
}
else if(chFilePath[i] == '\0')
{
break;
}
}
chFilePath[iLastSperate] = '\0';

if(iLastSperate == 2)
{
if(ERROR_ALREADY_EXISTS!=GetLastError())
{
return 3;//文件夹不存在但创建失败
}
return 1;//文件夹存在
}

strDir1 = chFilePath;
if(!CreateDirectory(strDir1,NULL))
{
int ret = CreateDir(strDir1);
if( 0 == ret)
{
if(!CreateDirectory(strDir,NULL))
{
if(ERROR_ALREADY_EXISTS!=GetLastError())
{
return 4;//文件夹不存在但创建失败
}
return 1;//文件夹存在
}
else
{
//创建成功
return 0;
}
}
else if(1 == ret)
{
//已存在!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
return 1;
}
else
{
//创建失败
return 2;
}
}
else
{
if(!CreateDirectory(strDir,NULL))
{
//创建失败!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
if(ERROR_ALREADY_EXISTS!=GetLastError())
{
return 2;//文件夹不存在但创建失败
}
return 1;//文件夹存在
}
else
{
//创建成功
return 0;
}
}
}
return 0;
}

/*********************************
函数名: RunEvent()
说明: 内部函数,记录每次运行事件
********************************/
void CLogFile::RunEvent(int type,CString strEvent)
{
EnterCriticalSection(&m_criticalsecRE);
//运行日志
CFile f;
CTime tmCurr = CTime::GetCurrentTime();
BOOL bRet = TRUE;
if(type == 0)
{
bRet = f.Open("GDW_BVPCommDllEvent.txt",CFile::modeCreate);
if(bRet)
{
f.Close();
}
}
else if(type == 1)
{
}

bRet = f.Open("GDW_BVPCommDllEvent.txt",
CFile::modeCreate|CFile::modeNoTruncate|CFile::modeWrite);
if(bRet)
{
if(f.GetLength() > 1024*1000)
{
f.Close();
f.Remove("GDW_BVPCommDllEvent.txt");
bRet = f.Open("GDW_BVPCommDllEvent.txt",
CFile::modeCreate|CFile::modeNoTruncate|CFile::modeWrite);
}

if(bRet)
{
CString strMsg;
strMsg = tmCurr.Format("%Y-%m-%d %H:%M:%S ");
strMsg += strEvent + "\r\n";
f.SeekToEnd();
f.Write((LPCTSTR)strMsg,strMsg.GetLength());
f.Close();
}
}
LeaveCriticalSection(&m_criticalsecRE);
}

/************************************
函数名: DspVersion(CString strEvent)
说明: 内部函数,记录每次运行事件
************************************/
void CLogFile::DspVersion(CString strEvent)
{
CFile f;
BOOL bRet= TRUE;
CString strFile;
CTime tmCurr = CTime::GetCurrentTime();
char achRunRecordFile[MAX_PATH];
// strFile = tmCurr.Format("%Y_%m.txt");
strFile = "DspVersion.txt";
sprintf(
achRunRecordFile,
"%s%s",
g_strRunPath, strFile
);
bRet = f.Open(
achRunRecordFile,
CFile::modeCreate|CFile::modeNoTruncate|CFile::modeWrite
);
if(bRet)
{
CString strMsg;
CString strTime;
strTime = tmCurr.Format("%Y-%m-%d %H:%M:%S ");
strMsg.Format("%s%s\r\n", strTime, strEvent);
f.SeekToEnd();
f.Write((LPCTSTR)strMsg, strMsg.GetLength());
f.Close();
}
}
icosagon 2008-04-15
  • 打赏
  • 举报
回复
ls上还要把=号和拷贝构造私有化
YFY 2008-04-15
  • 打赏
  • 举报
回复
上面的不是singleton模式的,今天查阅了一下要完美实现真蛮复杂的,还在研读中,有一个看上去不错:
class Singlton
{
private:
Singlton()
{
cout<<"object is ["<<this<<"] Do< Construction"<<endl;
}
public:
~Singlton()
{
cout<<"object is ["<<this<<"] Do Destruction>"<<endl;
}

static Singlton & GetSinglton()
{
static Singlton s;
return s;
}
void Dosomething()
{
cout<<"object is ["<<this<<"] Do Something"<<endl;
}
};

void foo(int i)
{
/*

程序体
*/
if(i)
Singlton::GetSinglton().Dosomething();
/*

程序体
*/
}
class TestSinglton
{
public:
TestSinglton()
{
Singlton::GetSinglton().Dosomething();
}
~TestSinglton()
{
Singlton::GetSinglton().Dosomething();
}
};
TestSinglton test1;
int main()
{
/*
void ;
程序体
*/
TestSinglton test2;
foo(1);
return 0;
}

yuzhongshan 2008-04-14
  • 打赏
  • 举报
回复
re 楼上:
静态存储的内存在程序开始就已分配好,在程序运行时一直存在,所以没必要释放
蓝光芒 2008-04-12
  • 打赏
  • 举报
回复
[Quote=引用 23 楼 yuzhongshan 的回复:]
引用 20 楼 Erorr 的回复:
噢,忘了把那个log赋个初值,


??
我感觉你的代码没什么问题
[/Quote]

是不是析构函数还需要释放内存阿。
yuzhongshan 2008-04-11
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 Erorr 的回复:]
噢,忘了把那个log赋个初值,
[/Quote]

??
我感觉你的代码没什么问题
hxxwcc 2008-04-02
  • 打赏
  • 举报
回复
楼主写的是momostate,见Agile Software Development Principles,Patterns,and Practice有详细描述

ps:为深莫不到3年不让进?lz,我也混进来了
挑战者I 2008-04-02
  • 打赏
  • 举报
回复
觉的楼主说的和singleton无关

jackylingzeng 2008-03-26
  • 打赏
  • 举报
回复
17楼这样写的 singleton 应该有问题吧,编译不知能不能通过,但运行时一定有问题。
jackylingzeng 2008-03-26
  • 打赏
  • 举报
回复
up 学习
Erorr 2008-03-26
  • 打赏
  • 举报
回复
噢,忘了把那个log赋个初值,然后往那里面写日志了
不过确实可以编译而且运行的,只不过日志输出到屏幕了
VC++6.0环境
我确实不懂DLL,所以只能保证exe可以运行
Erorr 2008-03-22
  • 打赏
  • 举报
回复
俺只有半年工作经验,也不知道dll,但单体总是有instance的吧,写个简单的单体:

#include <iostream>
#include <fstream>

using namespace std;

class LogFile
{
public:
void WriteError(const char* info)
{
cout << info << endl;
}

static LogFile* getInstance()
{
if (instance == NULL)
{
instance = new LogFile();
}
return instance;
}

protected:
LogFile(){
}
~LogFile();

static LogFile *instance;
//std::ofstream log;

} ;

LogFile *LogFile::instance = NULL;

int main()
{
LogFile::getInstance()->WriteError("hehe");
return 0;
}
葫芦鬼 2008-03-11
  • 打赏
  • 举报
回复
楼主还需要好好学习下设计模式
haierjodn 2008-03-06
  • 打赏
  • 举报
回复
sinosinux 2008-03-04
  • 打赏
  • 举报
回复
这个问题不需要三年经验 -_-||
abomber2 2008-03-04
  • 打赏
  • 举报
回复
没有包含头文件吧
BenjaminHuang 2008-03-04
  • 打赏
  • 举报
回复
思路没有表述清楚,不确切楼主是否真正懂得运用 Singleton 模式
zarelaky 2008-02-22
  • 打赏
  • 举报
回复
san
加载更多回复(10)

5,530

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 模式及实现
社区管理员
  • 模式及实现社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧