C++ Singleton Instance禁用重新调用

Vuw*_*wox 1 c++ singleton static c++11

使用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& );
};
Run Code Online (Sandbox Code Playgroud)

您可以按如下方式调用实例:

Singleton::instance().Hello();
Run Code Online (Sandbox Code Playgroud)

要么

Singleton& s = Singleton::instance();
s.Hello();
Run Code Online (Sandbox Code Playgroud)

但我想知道是否有办法阻止这个:

Singleton::instance().instance();
Run Code Online (Sandbox Code Playgroud)

如何避免调用instance()作为方法(带.)并且只支持静态调用::

有没有办法使用static_assert,模板enable_if或其他任何东西?

Bar*_*rry 7

首先,我认为这不是一个实际问题.没有人会写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;
}
Run Code Online (Sandbox Code Playgroud)

现在它只是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
Run Code Online (Sandbox Code Playgroud)