0

我正在尝试在使用Loki::FactoryVC8 编译的项目中使用(我不允许切换到较新的编译器)。程序退出时出现问题,我可以使用此基本代码重现该问题(这是您在使用工厂时可能想要实现的最起码)

#include "stdafx.h"
#include <loki/Factory.h>

struct Base{};
Loki::Factory< Base, int> factory;

struct Derived : public Base{};
Base* buildDerived(){
    return new Derived();
}
namespace {
    bool registeredD = factory.Register(1, buildDerived);
}

int _tmain(int argc, _TCHAR* argv[])
{
    system("pause");
    return 0;
}

一切都很好,直到系统暂停要求使用按键(如system("pause"));但是,当我按下键时,由于从函数内部抛出未处理的异常,程序中止

~auto_ptr()
{   // destroy the object
delete (_Ty *)_Myptr;
}

可以在 Visual Studio 文件“内存”中找到。异常是访问冲突,堆栈以:

compmgr.dll!std::auto_ptr<Loki::FunctorImpl<Interface2D::IElement *,Loki::NullType,Loki::SingleThreaded> >::~auto_ptr<Loki::FunctorImpl<Interface2D::IElement *,Loki::NullType,Loki::SingleThreaded> >()  Riga 718 + 0x32 byte  C++
    compmgr.dll!Loki::Functor<Interface2D::IElement *,Loki::NullType,Loki::SingleThreaded>::~Functor<Interface2D::IElement *,Loki::NullType,Loki::SingleThreaded>()  + 0x2b byte    C++

std::auto_ptr我在互联网上找不到任何关于使用Loki 的参考。

如何解决问题?

4

2 回答 2

1

因为我一直想看看 Loki 库,所以我利用了这个机会。好吧,首先,这个问题与 MSVC 版本无关,我确实在 VS2008 上运行了相同的示例,并且使用 VS2008 构建的 Loki 库得到了相同的结果。第二:

#include "stdafx.h"
#include <loki/Factory.h>
#pragma comment(lib, "loki_D.lib")
struct Base{};


struct Derived : public Base{};
Base* buildDerived(){
    return new Derived();
}

int _tmain(int argc, _TCHAR* argv[])
{
    Loki::Factory< Base, int> factory;
    bool registeredD = factory.Register(1, buildDerived);
    //system("pause");
    return 0;
}

这工作正常。我在您的示例中检查了崩溃,似乎工厂正在删除关联容器,您创建的仿函数应该在它已经被销毁之后所在的位置。在我看来,这是因为 Loki 正在连接atexit()并删除那里的一些东西(不知道为什么,我猜是为了处理 Singleton 对象),这就是你的 Functor 被删除的地方,然后在你的工厂的析构函数被调用然后对关联容器的erase调用失败。好吧 - 如果不是什么大不了的事,不要让工厂成为全局对象。如果这是一个大问题,请尝试调试并找出 Loki 为什么会做它所做的事情atexit,也许你需要设置更多的东西。但至少据我所知,这是另一个破坏全局对象的未定义行为的坏情况。

编辑:Loki Factory-Singleton 在 ARM 上的 try-catch-block 中抛出“检测到死引用”,宏 LOKI_FUNCTOR_IS_NOT_A_SMALLOBJECT 可能是相关的,因为我猜这会触发破坏,也许没有这个对象将不会进入对象列表毁于一旦,atexit但我对 Loki 库的了解还不够好。也许您需要定义单例的生命周期策略或类似的东西。

于 2013-09-02T08:58:12.307 回答
0

问题在于生命周期管理。我在这里报告解决方案以供参考:

#include "stdafx.h"
#include <loki/Factory.h>
#include <loki/Singleton.h>

struct Base{
    virtual ~Base(){};
};
typedef Loki::SingletonHolder< Loki::Factory<Base, int> > Factory;

struct Derived : public Base{};
Base* buildDerived(){
    return new Derived();
}
namespace {
    bool registeredD = Factory::Instance().Register(1, buildDerived);
}

int _tmain(int argc, _TCHAR* argv[])
{
    system("pause");
    return 0;
}
于 2013-09-03T09:43:01.620 回答