Дубликат экземпляра синглтона

Работая над крупным проектом, касающимся сотрудничества 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);

Это хороший интерфейс, который мы хотели бы продолжать использовать.

Мы хотим использовать этот класс в качестве замены для перечислений, потому что нам нужно перевести их из строки в строку. В этом классе у нас есть 2 члена «перечисления», а именно норма и ни одного.

Теперь мы добавили некоторые записи и определили, что операция вставки внутри функции none_string и norm_string вызывается дважды, хотя наш счетчик должен это предотвратить.

Некоторые вещи, которые мы попробовали:

  • Мы работаем с динамической библиотекой, но использование -rdynamic не помогло.
  • Когда мы печатаем адрес статических переменных, мы ясно видим, что они различаются.
  • Этот класс находится в динамической библиотеке, которая, в свою очередь, связана с mex-файлом. Этот mex-файл динамически загружается другим mex-файлом через dlopen.

Мы думали, что, возможно, несколько экземпляров этого класса объявлены и активны из-за динамической библиотеки. Но мы также используем другие виды синглетонов, которые не показали никаких признаков проблем.

Я надеюсь, что это было достаточно ясно, дополнительную информацию или разъяснения всегда можно предоставить!

Заранее спасибо!

0

Решение

Вы явно усложняете проблему.

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");
}

будет работать так же хорошо, если не лучше и быстрее.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]