gpt4 book ai didi

C++ 单例模板类使我的程序崩溃

转载 作者:太空宇宙 更新时间:2023-11-04 12:29:57 25 4
gpt4 key购买 nike

我创建了一个单例模式作为模板类。

template <typename T>
class TemplateSingleton
{
protected:
TemplateSingleton() { }
virtual ~TemplateSingleton() { }

public:
static T * GetInstance()
{
if (m_pInstance == NULL)
m_pInstance = new T;

return m_pInstance;
};

static void FreeInstance()
{
if (m_pInstance != NULL)
{
delete m_pInstance;
m_pInstance = NULL;
}
};

private:
static T * m_pInstance;
};

template <typename T> T * TemplateSingleton<T>::m_pInstance = NULL;

并使用继承自子类。该类可以通过继承模板作为单例使用,如果不继承则作为泛型类使用。

#define MAX_COUNT 8

class CDataHandler : public TemplateSingleton<CDataHandler>
{
public:
CDataHandler();
~CDataHandler();
...

private:
CDataObj m_clDataObj[MAX_COUNT]; // CDataObj *m_clDataObj ?
DWORD m_dwDataObjCount;
...
};

class CDataObj
{
public:
CDataObj();
~CDataObj();
...

private:
...
};

以上代码在一个DLL中,程序实现只调用CDataHandler的实例构造函数。我的程序崩溃并退出。

顺便说一下,如果我将 CDataObj 成员变量从数组更改为指针,它就可以正常工作。(在这种情况下,在 CDataHandler 的构造函数中新建,在析构函数中删除。)

这段代码有问题吗?

添加)CDataHandler 的构造函数和析构函数代码:)

CDataHandler::CDataHandler()
: m_dwDataObjCount(0)
//, m_clDataObj(NULL)
{
// Do nothing

// m_clDataObj = new CDataObj[MAX_COUNT];
}
CDataHandler::~CDataHandler()
{
//if (m_clDataObj != NULL)
{
for (int i = 0; i < MAX_COUNT; i++)
{
m_clDataObj[i].Close();
}

// delete[] m_clDataObj;
// m_clDataObj = NULL;
}
}

最佳答案

不确定是什么导致您的程序崩溃,但您发布的代码中存在两个潜在问题。

首先,您不知道m_pInstance 何时会被初始化为NULL。如果您在静态数据初始化期间调用 GetInstance()m_pInstance 可能尚未初始化为 NULL,因此 GetInstance() 将返回一些无效的指针。查找“static data initialisation order fiasko”之类的东西,这方面有很多信息。

为避免这种情况,您可以按照以下方式使用局部静态变量:

T* GetInstance()
{
static T* t = new T{};
return t;
}

其次,您为单例使用模板。没关系,但您必须注意:如果类的定义可用于多个编译单元,则这些编译单元中的每一个都将实例化自己的单例,根据您来自哪个编译单元,您将拥有多个不同的实例访问它们。

为了解决这个问题,可以对DLL中的某个T使用extern template来告诉别人不要实例化这个模板特化,然后编译一个显式的模板实例化放入 DLL 中,为大家提供实现。

关于C++ 单例模板类使我的程序崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59063044/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com