我有静态库,其中包含这样的单例定义:
class InstrumentsStorage
{
public:
static InstrumentsStorage& getInstance() {
static InstrumentsStorage instance;
return instance;
}
// methods
private:
InstrumentsStorage();
InstrumentsStorage(InstrumentsStorage const&);
void operator=(InstrumentsStorage const&);
// fields
};
我添加了这样的跟踪:
InstrumentsStorage::InstrumentsStorage() {
std::cout << "InstrumentsStorage constructor called!" << std::endl;
...
在我的日志中,我发现这个字符串两次。为什么?如何修复我的单例,因此只创建了一个实例。我可以使用C ++ 11。
我正在使用来自不同线程的不同项目的单例,但我只有一个进程。
更新添加完整列表:
#pragma once
#include <string>
#include <iostream>
#include <boost/unordered_map.hpp>
#include "CommonsNative.h"
class InstrumentsStorage
{
public:
static InstrumentsStorage& getInstance() {
static InstrumentsStorage instance;
return instance;
}
int GetInstrumentId(std::string& instrument);
std::string& GetClassCode(int instrumentId) {
return classcodes[instrumentId];
}
std::string& GetTicker(int instrumentId) {
return tickers[instrumentId];
}
private:
InstrumentsStorage();
InstrumentsStorage(InstrumentsStorage const&);
void operator=(InstrumentsStorage const&);
boost::unordered_map<std::string, int> instrument2id;
std::string classcodes[MAX_INSTRUMENTS_NUMBER_IN_SYSTEM];
std::string tickers[MAX_INSTRUMENTS_NUMBER_IN_SYSTEM];
};
cpp:
#include "InstrumentsStorage.h"
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/ini_parser.hpp>
#include <iostream>
InstrumentsStorage::InstrumentsStorage() {
std::cout << "InstrumentsStorage constructor called!" << std::endl;
boost::property_tree::ptree pt;
boost::property_tree::ini_parser::read_ini("config_generated/instruments_gate_0.txt", pt);
for (auto& section : pt)
{
std::string instrument = section.first;
int id = section.second.get_value<int>();
instrument2id[instrument] = id;
std::cout << "InstrumentsStorage Assigned instrument = " << instrument << " id = " << id << std::endl;
classcodes[id] = instrument.substr(0, 4);
tickers[id] = instrument.substr(4, std::string::npos);
std::cout << "InstrumentsStorage id " << id << " classcode = " << classcodes[id]
<< " ticker = " << tickers[id] << std::endl;
}
}
int InstrumentsStorage::GetInstrumentId(std::string& instrument)
{
// std::cout << "InstrumentsStorage GetInstrumentId called, instrument = " << instrument << std::endl;
boost::unordered_map<std::string, int>::iterator i = instrument2id.find(instrument);
if (i == instrument2id.end())
{
// std::cout << "InstrumentsStorage GetInstrumentId not found, result == -1 " << std::endl;
return -1;
} else
{
// std::cout << "InstrumentsStorage GetInstrumentId found, result = " << i->second << std::endl;
return i->second;
}
}
答案 0 :(得分:0)
如果您需要线程安全的单例,则必须实现自己的锁定机制。在C ++ 11中这样做的最简单方法是:
#include <mutex>
class Singleton
{
static Singleton *singletonInstance;
Singleton() {}
static std::mutex m_;
public:
static Singleton* getSingletonInstance()
{
std::lock_guard<std::mutex> lock(m_);
if(singletonInstance == nullptr)
{
singletonInstance = new Singleton();
}
return singletonInstance;
}
}
实现它的另一种方法,或许更简单,就是使用一次性函数:
#include <mutex>
static void init_singleton() {
singletonInstance = new Singleton;
}
static std::once_flag singleton_flag;
Singleton* getSingletonInstance() {
std::call_once(singleton_flag, init_singleton);
return singletonInstance;
}
即使您的编译器可能无法完全实现C ++ 11并发模型尚未,上述两种方法都可以工作:
static Foo& getSingleton() {
static Foo foo;
return foo;
}
将正常工作。
答案 1 :(得分:0)
我不确定您的问题是否已解决。看代码,似乎静态变量只应实例化一次,因此它的构造函数应该只被调用一次。可能是其他时间在您的代码中调用的构造函数。 你能在构造函数中设置断点并调试它来检查。它可以帮助您更快地找到问题。