单例的重复实例化
Duplicate instantiation of singleton
我们正在做一个关于c++和Matlab通过Mex合作的大型项目,目前我们正在努力解决我们的一个单例。
这个类是在预处理过程中通过宏生成的,所以看起来有点奇怪。
class AdditionalOperation {
private:
const std::string* val;
typedef std::map<std::string, const std::string*> StringMap;
static StringMap& getStringToPointerMap()
{
static StringMap map;
return map;
}
static boost::mutex& getMutex()
{
static boost::mutex mutex;
return mutex;
}
AdditionalOperation(const std::string* s)
:val(s)
{}
private:
static std::string* none_string()
{
static std::string s = "none";
static int count = 0;
boost::mutex::scoped_lock lock(getMutex());
if(count++ == 0) {
getStringToPointerMap().insert(std::make_pair(s,&s));
}
return &s;
}
public:
static AdditionalOperation none()
{
return AdditionalOperation(none_string());
}
private:
static std::string* norm_string()
{
static std::string s = "norm";
static int count = 0;
boost::mutex::scoped_lock lock(getMutex());
if(count++ == 0) {
getStringToPointerMap().insert(std::make_pair(s,&s));
}
return &s;
}
public:
static AdditionalOperation norm()
{
return AdditionalOperation(norm_string());
}
private:
static void prepare()
{
none();
norm();
}
public:
static AdditionalOperation fromString(std::string s)
{
static int count = 0;
if(count++ == 0)
prepare();
boost::mutex::scoped_lock lock(getMutex());
StringMap& map = getStringToPointerMap();
StringMap::iterator location = map.find(s);
if(location == map.end()) {
throw UnknownEnumValue(s);
}
return AdditionalOperation(location->second);
}
std::string toString() const
{
return *val;
}
bool operator==(const AdditionalOperation& other) const
{
return val == other.val;
}
bool operator!=(const AdditionalOperation& other) const
{
return !(*this == other);
}
};
所有这些代码都是从这一行生成的(通过如上所述的宏):
DECLARE_SENUM(AdditionalOperation, none, norm);
这是一个很好的界面,我们想继续使用。
我们希望使用该类作为枚举的替代品,因为我们需要将它们从字符串转换为字符串。在这个类中,我们有两个"枚举"成员,即norm和none。
现在我们已经添加了一些日志记录,并且已经确定none_string和norm_string函数中的插入操作被调用了两次,尽管我们的计数器应该防止这种情况发生。
我们尝试过的一些事情:
- 我们正在使用一个动态库,但是使用-rdynamic没有帮助。 当我们打印静态变量的地址时,我们可以清楚地看到它们的不同。这个类位于一个动态库中,这个动态库又与一个mex文件链接。这个mex文件是由另一个mex文件通过dlopen动态加载的。
我们认为可能由于动态库的关系,该类的多个实例被声明并激活。但是我们也使用其他类型的单例,这些单例没有显示出任何问题的迹象。
我希望它足够清楚,可以随时提供额外的信息或澄清!
提前感谢!
很明显,你把问题复杂化了。
std::string const& to_string(MyEnum e) {
static std::string const First = "First";
static std::string const Second = "Second";
switch(e) {
case MyEnum::First: return First;
case MyEnum::Second: return Second;
}
throw std::runtime_error("Unknown enum value");
}
相关文章:
- C++中的单例实现在调用 getInstance 函数时不会产生相同的类实例
- 如何析构单例实例,或者为什么以下代码适用于析构函数?
- C++在单例类中创建类实例时遇到困难
- 继承的模板化单例类 c++ 中未定义的构造函数
- 使用新线程在类似于 Scott Meyer 的单例习惯用法的实现中实例化单例是否安全?
- 隐藏的单例,用于封装初始化和销毁代码
- XCode5.1 C 静态单例,但创建了多个实例
- 懒惰的初始化使用单例模式
- 正在初始化单例的常量成员变量
- c++单例类实例访问整个应用程序
- 如何检查是否存在单例实例,如果没有,则不创建新实例?
- 指针成员的 C++/CLI 包装器 - C++ 单例实例
- 强制初始化单例类
- 可视化 如何在 C++/CX 中创建单例
- 单例实例化了两次
- 当周围有线程时,创建类的许多实例会失败吗?- 单例模式
- 为什么C++单例实例化需要do_nothing方法
- 用于初始化实例的单例
- 在c++类中初始化单例
- 单例的重复实例化