使用 Meyers 单例时:
class Singleton
{
public:
static Singleton& instance()
{
static Singleton instance;
return instance;
}
void Hello()
{
std::cout <<"Hello!\n";
}
protected:
Singleton() = default;
~Singleton() {};
private:
Singleton(Singleton const&);
Singleton& operator=( Singleton const& );
};
您可以按如下方式调用实例:
Singleton::instance().Hello();
或
Singleton& s = Singleton::instance();
s.Hello();
但我想知道是否有办法阻止它:
Singleton::instance().instance();
如何避免将 instance() 作为方法调用(使用 .
)并且仅支持使用 ::
的静态调用?
有没有办法使用 static_assert、模板 enable_if 或其他任何东西?
最佳答案
首先,我认为这不是一个实际问题。没有人会写 Singleton::instance().instance().instance().Hello()
。或者更确切地说,如果人们是故意写的,我认为你有更大的问题。这很好,照原样。
如果你真的想阻止这种情况,那么你只需要将 instance()
移到类之外,这样它就不再是成员函数了。你没有什么可以断言或约束的,因为你无法判断你的静态成员函数是否在对象上被调用(并且你不能用采用相同参数列表的非静态成员函数重载静态成员函数)。您可以同时编写 Singleton::instance()
和 Singleton::instance().instance()
,或者两者都不写。
最简单的就是:
class Singleton {
// ...
friend Singleton& make_singleton();
};
Singleton& make_singleton() {
static Singleton instance;
return instance;
}
现在只有 make_singleton().Hello()
,而且根本没有其他方法可以编写它。这可以通过将其包装在单例类模板工厂中任意概括:
template <typename T>
struct SingletonFactory
static T& instance() {
static T instance;
return instance;
}
};
SingletonFactory<Singleton>::instance().Hello(); // ok
SingletonFactory<Singleton>::instance().instance().Hello(); // error
关于C++ 单例实例禁用重新调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51597208/