我有一个单身人士(我知道这是一个糟糕的模式)。为了控制清理过程,我正在使用共享指针。相关代码是:
#ifndef _GLOBAL_LOG_H_
#define _GLOBAL_LOG_H_
namespace glog{
class CGlobalLog;
typedef boost::shared_ptr<CGlobalLog> globalLogPtr;
class CGlobalLog
{
private:
static globalLogPtr m_instance;
LogLevel minimiumLogLevel;
CGlobalLog(void);
static void deleter(CGlobalLog *ptr){
try{
delete ptr;
}
catch(std:: e)
{
std::cout << e.what() << "\n";
}
}
static void create() { m_instance.reset( new CGlobalLog, &CGlobalLog::deleter ); }
void addMessage_(const std::string& appender, LogLevel level /*= LOGLEVEL_INFO*/,const char* msg, va_list args );
~CGlobalLog(void);
public:
static globalLogPtr& getInstance();
void addMessage(const std::string& message, std::string appender, LogLevel level = LOGLEVEL_INFO);
};
globalLogPtr CGlobalLog::m_instance;
};
#endif // _GLOBAL_LOG_H_
程序工作正常,但程序完成后,会抛出未处理的异常:
static void deleter(CGlobalLog *ptr){
try{
delete ptr; //<-- Unhandled exception
}
catch(std:: e)
{
std::cout << e.what() << "\n";
}
}
catch没有捕获异常,所以我不知道如何分析我的错误。抛出错误的确切代码是boost库文件checked_delete.hpp,这里:
// verify that types are complete for increased safety
template<class T> inline void checked_delete(T * x)
{
// intentionally complex - simplification causes regressions
typedef char type_must_be_complete[ sizeof(T)? 1: -1 ];
(void) sizeof(type_must_be_complete);
delete x;
}
如何找到此错误?一些想法?
感谢!!!
答案 0 :(得分:1)
我通常不希望在单例上看到共享指针。只需返回对你的单身人士的引用,并且永远不会保留对它的引用是一种很好的做法。
struct Foo {
static Foo &instance() {
static Foo foo;
return foo;
}
};
struct Bar {
void someMethod() {
Foo &foo = Foo::instance(); // just grab a reference every time you need it
// ...
}
};
如果您希望保留共享指针并需要以手动方式清理资源,请创建拆卸方法。 boost::shared_ptr
最终会清理内存。
就我个人而言,我认为外部使用共享指针是劣等的。我写了一些代码来演示拆卸,如果不知道为什么需要拆卸它,它似乎并不普遍适用。
如果要显式删除,请写一个。
struct Foo {
static Foo *foo = 0;
static Foo &instance() {
if (!foo)
throw std::logic_error("Already deleted");
return *foo;
}
static void Init() {
if (foo)
throw std::logic_error("Already created");
foo = new Foo;
}
static void Destroy() {
if (!foo)
throw std::logic_error("Already deleted");
delete foo;
foo = 0;
}
};
在记录的情况下,逻辑错误应该是多余的。如果您要求记录无效,则您的应用程序不太可能处于有效状态。