我的项目中需要一个注册表,它可以容纳某些状态,并且可以从代码中的任何位置轻松访问。 Singleton是我们已经在经典实现中使用的东西 静态X& X ::实例() { 静态X实例; 返回实例; } 但这会导致UT出现问题。我提出了这样一个想法
smartSingletonWrapper.h
class smartSingletonWrapper
{
public:
smartSingletonWrapper(arg_for_Actual_Singleton)
{
instance.reset(make_shared<Actual_Singleton>(arg_for_Actual_Singleton));
}
~smartSingletonWrapper()
{
assert(instance.count() == 1, "In case you want sanity checks");
instace.reset();
}
static shared_ptr<Actual_Singleton> getInstance() //or weak_ptr
{
return instance;
}
private:
static shared_ptr<Actual_Singleton> instance;
class Actual_Singleton //or implement elsewhere with private constructor and wrapper as friend class
{
//stuff..
}
}
smartSingletonWrapper.cpp
shared_ptr<Actual_Singleton> smartSingletonWrapper::instance;
现在使用它将是:
int main(argc, argv)
{
smartSingletonWrapper raii_singleton_holder;
invoke_milions_lines_of_code();
return 0;
}
在非常好的同样的故事中,只需在1次测试结束后在任何地方创建该对象。基于gtest的示例:
class ut_class_using_actual_singleton : public testing::Test
{
public:
class_using_actual_singleton system_under_test;
smartSingletonWrapper
};
TEST_F(ut_class_using_actual_singleton, some_test)
{
test_stuff();
}
这是一个简单但有效的版本。你可以通过使这个类成为一个接受其中任何类型的单例类的模板来增强它。您可以添加健全性检查(例如,检查此smartSingleton是否只有一个实例)。
有没有人发现这个想法有任何问题?有没有人听说过类似的想法?我不相信我实际上发明了以前从未描述过的东西。