C++ 单例实例禁用重新调用

标签 c++ c++11 static singleton

使用 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/

相关文章:

c++ - 政策是概念吗?

c++ - 如何使 qtcreator 与 c++11 一起工作

c++ - unordered_map/unordered_set 中元组的通用哈希

c++11 - 在现代 C++ 中重载算术运算符的 "best"方法是什么?

c++ - 为什么不能在 C++ 中将构造函数声明为静态的?

c++ - 为什么即使在 const 函数中也会更改值?

c# - 如何为 Java、C# 和 C++ 中的一个项目的不同实现管理一份一致的文档?

c++ - 从 char* move std::string 的构造函数

c++ - 纯抽象类可以包含静态常量、静态方法或非虚拟析构函数吗?

java - Java 中的静态和非静态 vs 泛型和通配符