[英]c++ std::unordered_map singleton access violation error
template <typename T> class singleton
{
public:
static T* ms_singleton;
singleton()
{
assert(!ms_singleton);
long offset = (long)(T*)1 - (long)(singleton <T>*) (T*) 1;
ms_singleton = (T*)((long)this + offset);
}
virtual ~singleton()
{
assert(ms_singleton);
ms_singleton = 0;
}
static T& Instance()
{
assert(ms_singleton);
return (*ms_singleton);
}
static T* instance_ptr()
{
return (ms_singleton);
}
};
class Test
{
private:
DWORD X;
}
typedef Test* LPTEST;
class TestManager : public singleton<TestManager>
{
public:
TestManager();
virtual ~TestManager();
LPTEST CreateTest(DWORD id);
protected:
private:
std::unordered_map<DWORD, LPTEST> test_map;
};
LPTEST TestManager::CreateTest(DWORD id)
{
LPTEST test = new Test;
if (id)
{
test_map.insert(std::make_pair(id, test));
}
return (test);
}
我创建了一个类似的代码。
当我运行以下 function 时。
LPTEST 测试 = TestManager::Instance().CreateTest(61);
但“test_map.insert”给出了访问冲突错误。
test_map.insert -> 如果我关闭 function 它工作正常。
所有代码都正常。 为什么我对 std:map 之类的代码有这样的问题。
如果你能帮忙,我会很高兴。
通过如下更改 Singleton 代码。 我解决了这个问题。
template <typename T> class singleton
{
public:
singleton() {}
~singleton() {}
static T& Instance()
{
static T instance;
return instance;
}
singleton(const singleton&) = delete;
singleton& operator=(const singleton&) = delete;
};
@drescherjm,@UnholySheep 感谢您的帮助。
是不是觉得这段代码中有一段代码会在以后造成麻烦? 这段代码可以更好吗? 如何?
您的代码太复杂、危险并且充满了未定义的行为。
以下是一些问题:
offset
计算完全没有意义!static_cast
, dynamic_cast
完全理解为什么使用这种转换。在实践中,使用 Meyer 的 singleton,您很少需要定义这样的模板。
这样的事情要简单得多:
using TestMap = std::unordered_map<DWORD, Test>;
class TestManager
{
public:
static TestMap &GetTestMap();
Test *CreateTest(DWORD id);
};
// testmanager.cpp
TestMap &TestManager::GetTestMap()
{
// Creation of the object is thread safe but if you want
// to use it from multiple threads, you have to provide
// your own synchronisation like mutex.
static TestMap testMap;
return testMap;
}
Test *TestManager::CreateTest(DWORD id)
{
// allocate a pair and return a reference to value
// if key already exist, return a reference to existing value.
auto &mapValue = GetTestMap()[id];
// as unique_ptr are stored in the map,
// memory managment can be simplified
// could also use make_unique here
mapValue.reset(new Test);
// return a raw pointer as in your original code
return mapValue.get();
}
根据需要和您对 C++ 的理解程度,该代码可以改进...正如所写,一旦您了解一些基本的 C++ 11,就很容易理解。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.